Astro can't find Sharp

The upgrade to Astro 4 has been painless, but the same simple issues come up enough that I thought I'd document the fix for anyone else encountering similarly sticky spots.

If you’re running Astro with Sharp and pnpm you may encounter this same issue. Thankfully the fix is reasonably simple once you know what’s causing the problem.

If you’d like to skip over my subjective criticism of the behaviour of a number of GitHub-hosted projects, you can just straight to the fix.

Problem

I ran into the error when running end-to-end tests with Playwright (do you misspell that bloomin’ name all the time too or is it just me?):

 generating optimized images
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

MissingSharp: Could not find Sharp. Please install Sharp (`sharp`) manually into your project or migrate to another image service.
    at loadSharp (file:///Users/fe/ghetto/dist/chunks/astro/assets-service_y5vnNTS5.mjs:381:11)
    at async Object.transform (file:///Users/fe/ghetto/dist/chunks/astro/assets-service_y5vnNTS5.mjs:393:15)
    at async generateImageInternal (file:///Users/fe/ghetto/node_modules/.pnpm/astro@4.0.4_@types+node@14.18.33_typescript@5.3.3/node_modules/astro/dist/assets/build/generate.js:119:24)
    at async generateImage (file:///Users/fe/ghetto/node_modules/.pnpm/astro@4.0.4_@types+node@14.18.33_typescript@5.3.3/node_modules/astro/dist/assets/build/generate.js:66:28)
    at async file:///Users/fe/ghetto/node_modules/.pnpm/p-queue@7.4.1/node_modules/p-queue/dist/index.js:118:36 {
  loc: undefined,
  title: 'Could not find Sharp.',
  hint: "See Sharp's installation instructions for more information: https://sharp.pixelplumbing.com/install. If you are not relying on `astro:assets` to optimize, transform, or process any images, you can configure a passthrough image service instead of installing Sharp. See https://docs.astro.build/en/reference/errors/missing-sharp for more information.\n" +
    '\n' +
    'See https://docs.astro.build/en/guides/images/#default-image-service for more information on how to migrate to another image service.',
  frame: undefined,
  type: 'AstroError'
}

The misguided suggestion told me to manually install a dependency that was already installed via an explicit entry in package.json and a mandatory invocation of pnpm install. While these inaccurate suggestions are common place enough you become blind to them, it’s worth remembering that these half-arsed attempts at helping others compound to make working with computers the inexcusably inaccessible mess that we’re all so ready to advertise to our friends and family.

Just rebuild

Now, I’ve had problems with Sharp multiple times before due to its reliance on architecture-specific code written in C++, so I know running a quick rebuild normally has us back up and running, but this time things were different.

$ pnpm rebuild sharp
node_modules/.pnpm/sharp@0.32.6/node_modules/sharp: Running install script, done in 351ms
node_modules/.pnpm/sharp@0.33.2/node_modules/sharp: Running install script, done in 91ms

Thinly-veiled contempt

Another attempt at running my integration tests presented the same error about not being able to find Sharp, so I fired up Kagi via Launchbar, and found my way to this rather anemic page in the Astro docs where someone struggles to hide their disdain for pnpm:

Sharp is the default image service used for astro:assets. When using a strict package manager like pnpm, Sharp must be installed manually into your project in order to use image processing.

Strict isn’t a word I’d use to describe the Javascript ecosystem, and pnpm’s use of hard links and a content-addressable store hardly seems fastidious.

As well as the documentation being less than helpful, a report of this issue was closed unceremoniously when the maintainers decided “there’s nothing actionable at this time”. Fortunately, help (and action) is at hand!

The fix

If rebuilding Sharp doesn’t resolve this issue, you likely need to update or reinstall libvips. In my case, I’m using Nix to manage Sharp’s dependencies so the following steps fixed things for me:

nix flake update
direnv reload # unless you're get this automatically via direnv
pnpm install

For anyone using Homebrew, your best bet (as least when I was last using Homebrew) is to reinstall using a two step process:

brew uninstall vips
brew install vips

It may be the case that brew reinstall works reliably but I came across enough reports of needing to uninstall and then install that it’s now trained behaviour where I’ll beat other primates over the head when they attempt to climb that ladder.

References