Skip to content

Commit bc4c1c5

Browse files
committed
fix(media/image): expand sharp-install hint to cover global installs
Codex review on PR #77197 noted: the previous hint suggested local install commands (pnpm add sharp / npm install sharp / bun add sharp) but the scenario operators most often hit is a global `npm install -g openclaw` where the global runtime resolves `sharp` from openclaw's own global node_modules, so a workspace install does not actually fix the failure on restart. Expand the thrown error to include both repair postures: the existing local commands plus an explicit global path (`npm install -g openclaw@latest --include=optional` or `npm install -g sharp`) so operators on either install posture get a working remediation. Update the regression test to assert both surfaces appear in the message.
1 parent 6842bd5 commit bc4c1c5

2 files changed

Lines changed: 24 additions & 5 deletions

File tree

src/media/web-media.test.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,18 +167,28 @@ describe("loadWebMedia", () => {
167167
// (e.g. the `image` agent tool) on hosts that skipped the optional `sharp`
168168
// native dep used to see a generic "Failed to optimize image" with the raw
169169
// module-resolution error tail, with no install hint. The thrown error now
170-
// explicitly names the missing dep and the install command.
171-
it("surfaces a clear sharp-install hint when the optional optimizer is unavailable (#73148)", async () => {
170+
// explicitly names the missing dep and includes both the local-checkout and
171+
// global-install repair commands so operators on either install posture get
172+
// a working remediation.
173+
it("surfaces a clear sharp-install hint covering both local and global installs when the optional optimizer is unavailable (#73148)", async () => {
172174
await withUnavailableImageOptimizer(async () => {
173175
const { optimizeImageToJpeg: optimizeImageToJpegWithMissingOptimizer } =
174176
await import("./web-media.js");
175177
const promise = optimizeImageToJpegWithMissingOptimizer(
176178
Buffer.from(TINY_PNG_BASE64, "base64"),
177179
8,
178180
);
179-
await expect(promise).rejects.toThrow(
180-
/requires the optional `sharp` native dependency.*pnpm add sharp/i,
181+
const error = await promise.then(
182+
() => null,
183+
(err: unknown) => err,
181184
);
185+
expect(error).toBeInstanceOf(Error);
186+
const message = (error as Error).message;
187+
expect(message).toMatch(/requires the optional `sharp` native dependency/i);
188+
// Local-install repair command (workspace checkout).
189+
expect(message).toMatch(/pnpm add sharp/);
190+
// Global-install repair command (npm -g openclaw users).
191+
expect(message).toMatch(/npm install -g openclaw@latest --include=optional/);
182192
});
183193
});
184194

src/media/web-media.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,11 +705,20 @@ export async function optimizeImageToJpeg(
705705
// resize attempt throws "Cannot find module 'sharp'". Surface a clear,
706706
// actionable hint so operators know what to install instead of a generic
707707
// "Failed to optimize image" with the raw module-resolution error tail.
708+
// The hint covers both common scenarios:
709+
// - Local repo checkout: install `sharp` in the workspace.
710+
// - Global install (e.g. `npm install -g openclaw@latest`): a workspace
711+
// `pnpm add sharp` won't help because the global runtime resolves
712+
// `sharp` from the global openclaw `node_modules`. Reinstalling the
713+
// globally installed openclaw with optional deps included rebuilds the
714+
// `sharp` prebuilt for the host platform.
708715
// See #73148.
709716
if (isOptionalImageOptimizerUnavailable(firstResizeError)) {
710717
throw new Error(
711718
"Image optimization requires the optional `sharp` native dependency, which is not installed. " +
712-
"Install it with `pnpm add sharp` (or `npm install sharp` / `bun add sharp`) and restart the gateway.",
719+
"Local repo install: `pnpm add sharp` (or `npm install sharp` / `bun add sharp`) and restart the gateway. " +
720+
"Global install: reinstall openclaw with optional deps included, e.g. `npm install -g openclaw@latest --include=optional` " +
721+
"(or `npm install -g sharp` if you cannot reinstall openclaw), then restart the gateway.",
713722
{ cause: firstResizeError },
714723
);
715724
}

0 commit comments

Comments
 (0)