fix(update): guide EACCES manual recovery

This commit is contained in:
brokemac79
2026-05-18 21:55:16 +01:00
committed by Peter Steinberger
parent 583eb711ec
commit 26bcc95665
3 changed files with 38 additions and 4 deletions

View File

@@ -64,6 +64,7 @@ describe("inferUpdateFailureHints", () => {
const hints = inferUpdateFailureHints(result);
expect(hints.join("\n")).toContain("EACCES");
expect(hints.join("\n")).toContain("npm config set prefix ~/.local");
expect(hints.join("\n")).toContain("stop the Gateway first");
});
it("returns EACCES hint for staged package permission failures", () => {
@@ -74,6 +75,9 @@ describe("inferUpdateFailureHints", () => {
const hints = inferUpdateFailureHints(result);
expect(hints.join("\n")).toContain("EACCES");
expect(hints.join("\n")).toContain("npm config set prefix ~/.local");
expect(hints.join("\n")).toContain("<system-npm>");
expect(hints.join("\n")).toContain("gateway install --force");
expect(hints.join("\n")).toContain("gateway restart");
});
it("returns native optional dependency hint for node-gyp failures", () => {

View File

@@ -85,7 +85,13 @@ export function inferUpdateFailureHints(result: UpdateRunResult): string[] {
hints.push(
"Detected permission failure (EACCES). Re-run with a writable global prefix or sudo (for system-managed Node installs).",
);
hints.push(
"If you recover with sudo/manual package install on a managed Gateway, stop the Gateway first so it does not load files while the package tree is being replaced.",
);
hints.push("Example: npm config set prefix ~/.local && npm i -g openclaw@latest");
hints.push(
"System install outline: openclaw gateway stop -> sudo <system-npm> i -g openclaw@latest -> openclaw gateway install --force -> openclaw gateway restart.",
);
}
if (