gatsby: gatsby-plugin-sharp: WorkerError @2.6.27

Description

Error processing a .png file when running gatsby develop

Steps to reproduce

Upgrading gatsby-plugin-sharp to version 2.6.27

Expected result

Images would be queried as expected

Actual result

image

Environment

System: OS: Linux 5.4 Ubuntu 20.04.1 LTS (Focal Fossa) CPU: (8) x64 AMD Ryzen 7 2700U with Radeon Vega Mobile Gfx Shell: 5.0.17 - /bin/bash Binaries: Node: 12.16.1 - ~/.nvm/versions/node/v12.16.1/bin/node Yarn: 1.22.4 - /usr/bin/yarn npm: 6.13.4 - ~/.nvm/versions/node/v12.16.1/bin/npm Languages: Python: 2.7.18 - /usr/bin/python Browsers: Chrome: 84.0.4147.105 Firefox: 80.0 npmPackages: gatsby: ^2.23.12 => 2.24.53 gatsby-background-image: ^1.1.1 => 1.1.2 gatsby-image: ^2.4.15 => 2.4.16 gatsby-plugin-google-analytics: ^2.3.13 => 2.3.13 gatsby-plugin-layout: ^1.3.10 => 1.3.10 gatsby-plugin-manifest: ^2.4.21 => 2.4.27 gatsby-plugin-module-resolver: ^1.0.3 => 1.0.3 gatsby-plugin-offline: ^3.2.21 => 3.2.26 gatsby-plugin-react-helmet: ^3.3.10 => 3.3.10 gatsby-plugin-react-svg: ^3.0.0 => 3.0.0 gatsby-plugin-sharp: 2.6.26 => 2.6.26 gatsby-source-filesystem: ^2.3.24 => 2.3.27 gatsby-source-graphql: ^2.7.1 => 2.7.2 gatsby-transformer-sharp: ^2.5.13 => 2.5.14

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 19
  • Comments: 47 (14 by maintainers)

Commits related to this issue

Most upvoted comments

My current solution is to downgrade gatsby-plugin-sharp to version 2.6.26.

NOTE: this was a preliminary post as I was chasing the problem with my system. Eventually I realized by instrumenting and running the pngquant binary manually that everything was working. It turns out that the imagemin-pngquant has special handling to look for exit code “99”. Unfortunately, the way to access this change from error.code to error.exitCode.

When I forced the verbose option and added some logging in the (mentioned below) index.js routine, I realized that “error.code” was returning EPIPE (means connection no longer there) or undefined. Since it always worked (regardless of quality parameter) when I ran pngquant manually from command line, I assumed there was a problem with the invocation of the binary through execa.

BTW the package in question is at https://github.com/imagemin/imagemin-pngquant The underlying binary is at https://pngquant.org/ In the notes on binary, you will see the standard (for this package) practice of returning exit code 99 whenever the output ends up being the same as the input due to characteristics of the input image and the requested quality parameter. The imagemin-pngquant routine was trying to catch this. But, we need to make a change to the reference as shown below.

Here is the patch that seems to work. Using package imagemin-pngquant with version 9.0.0, look at index.js Change this code (literally just error.code to error.exitCode):

	const promise = subprocess
		.then(result => result.stdout) // eslint-disable-line promise/prefer-await-to-then
		.catch(error => {
			if (error.code === 99) {
				return input;
			}

			error.message = error.stderr || error.message;
			throw error;
		});

To this:

	const promise = subprocess
		.then(result => result.stdout) // eslint-disable-line promise/prefer-await-to-then
		.catch(error => {
			if (error.exitCode === 99) {
				return input;
			}

			error.message = error.stderr || error.message;
			throw error;
		});

I will leave some of the details here for others to verify… Chasing some issues in which the pngquant invocation returns an error code that in index.js shows as “undefined” (should be 99) so the imagemin-pngquant routine will realize it is ok to skip the particular attempt…running the binary manually always gets a 99. When this code happens, the input is returned as output (ie no change). So, the question is why does an error code of undefined appear sometimes?

I have been seeing the same issues since recent updates of sharp-related libraries. After convincing myself there were no cache issues, I then homed in on failing PNG handling. Then I thought it was transparent PNG only. In the end, I think there are timing issues in how long the executable runs before the subprocess exits. Finally, I realized the code in imagemin-pngquant was checking the wrong element (error.code). Once I changed to error.exitCode, everything worked.

For reference, here is my environment (using v9.0.0 of imagemin-pngquant), from gatsby info:

gatsby info
  System:
    OS: Linux 5.4 Ubuntu 20.04.1 LTS (Focal Fossa)
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Shell: 5.0.17 - /bin/bash

  Binaries:
    Node: 12.18.3 - ~/.nvm/versions/node/v12.18.3/bin/node
    npm: 6.14.8 - ~/.nvm/versions/node/v12.18.3/bin/npm
  Languages:
    Python: 2.7.18 - /usr/bin/python
  Browsers:
    Firefox: 80.0
  npmPackages:
    gatsby: ^2.24.53 => 2.24.53
    gatsby-background-image: ^1.1.2 => 1.1.2
    gatsby-image: ^2.4.16 => 2.4.16
    gatsby-plugin-catch-links: ^2.3.11 => 2.3.11
    gatsby-plugin-google-analytics: ^2.3.13 => 2.3.13
    gatsby-plugin-google-tagmanager: ^2.3.11 => 2.3.11
    gatsby-plugin-manifest: ^2.4.27 => 2.4.27
    gatsby-plugin-offline: ^3.2.26 => 3.2.26
    gatsby-plugin-react-helmet: ^3.3.10 => 3.3.10
    gatsby-plugin-sharp: ^2.6.31 => 2.6.31
    gatsby-remark-component: ^1.1.3 => 1.1.3
    gatsby-remark-copy-linked-files: ^2.3.13 => 2.3.13
    gatsby-remark-images: ^3.3.28 => 3.3.28
    gatsby-remark-relative-images: ^0.3.0 => 0.3.0
    gatsby-source-filesystem: ^2.3.27 => 2.3.27
    gatsby-transformer-remark: ^2.8.32 => 2.8.32
    gatsby-transformer-sharp: ^2.5.14 => 2.5.14
  npmGlobalPackages:
    gatsby-cli: 2.12.91
    gatsby-starter-default: 0.1.0

And a quick check shows pngquant itself is version 2.10.1 on my machine (pulled from the packages under node_modules/pngquant-bin)

I’ll sort out a pull request once I am sure there are no negative effects - doing the above at least allowed things to build and images to process.

BTW, this is the detailed “error” that results when running the pngquant binary manually (an error code 99):

Original error:
stdin:
  read 8KB file
  made histogram...693 colors found
  selecting colors...3%
  selecting colors...24%
  selecting colors...27%
  selecting colors...48%
  selecting colors...51%
  selecting colors...72%
  selecting colors...93%
  selecting colors...100%
  moving colormap towards local minimum
  image degradation MSE=0.049 (Q=99) exceeded limit of 0.000 (100)
  writing truecolor image to stdout
Skipped 1 file out of a total of 1 file.

Note - on that “error” above, pngquant is just saying “I can’t do this so use the input as output”. From command line, the return code is 99. Eventually I sorted this out as mentioned above.

When I have the quality argument set to 100 I get the error, once I changed quality to a number like 90 it works again.

      image {
        childImageSharp {
          fluid(maxWidth: 1200, quality: 90) {
            ...GatsbyImageSharpFluid
          }
        }
      }

after so long time I found this bug issue…

On this place they closed. https://github.com/gatsbyjs/gatsby/issues/21515

Looks like imagemin-pngquant changed from v6 to v9

Looks like the error is swallowed so here is the real error: Command failed with exit code 99: ccc\\node_modules\\pngquant-bin\\vendor\\pngquant.exe - --strip --quality 100-100

failed for me in 2 projects already. Just deleted node_modules and yarn lock, then install and boom… fails

(spent a few solid hours figuring out what’s the problem, between deleting node_modules…etc)

Downgrading I’m getting this error Gatsby-plugin-sharp wasn't setup correctly in gatsby-config.js. Make sure you add it to the plugins array. - if fixed by making sure in yarn lock there is no reference to the new version of Gatsby-plugin-sharp

I just wanted to confirm that I am having the same error since updating all my dependencies today.

Thank you @davet42, your solution works every time (whilst upgrading and downgrading gatsby-plugin-sharp to any version makes no difference)! While waiting for your pull request to be merged I resolved hacked my build process in Dockerfile (before running gatsby build) ensuring the same code as your pull request in imagemin-pngquant:

RUN sed -i 's/error\.code[[:space:]]===[[:space:]]99/error.exitCode===99/' /your_app_path/node_modules/imagemin-pngquant/index.js

Hopefully someone will find it useful

I faced the same issue after upgrading gatsby-plugin-sharp from 2.6.2 --> 2.6.31. Then downgraded to 2.6.30 but didn’t resolve the issue. I did the following just to resolve it for now but not sure it’s the right way to do it

rm -rf node_module
rm package-lock.json
npm install

I started to get this error with the most recent version 2.6.31. Downgrading to 2.6.30 fixed the problem for now. I also have my quality setting as 100, although haven’t tried reducing that to fix the issue on the most recent version.

When I have the quality argument set to 100 I get the error, once I changed quality to a number like 90 it works again.

      image {
        childImageSharp {
          fluid(maxWidth: 1200, quality: 90) {
            ...GatsbyImageSharpFluid
          }
        }
      }

So far this is the only thing that works for me. Thank you @t2ca .

Can you try with yarn add gatsby-plugin-sharp@png-revert --registry=https://registry.wardpeet.dev

I met the same problem. I solved it through upgrade gatsby and gatsby-transformer-sharp both

Thanks @theinhtut , your solution works.

thanks @theinhtut your solution worked for me.

No but I’ve just update the machine that I use to have a more powerful one, works perfectly now

@wardpeet looks like imagemin/imagemin-pngquant#71 was merged - I guess imagemin-pngquant can be bumped to 9.0.1 now to see if it still causes this error.

I’ve tried, the update works great on my side, on local and Netlify 🎉

Workaround with latest versions of plugins (without changing the quality)

  1. Install patch-package (npm install patch-package or yarn add patch-package postinstall-postinstall)
  2. Add "postinstall": "patch-package" to scripts in package.json
  3. Go into node_modules/imagemin-pngquant/index.js and change error.code to error.exitCode on line 66 (see diff below)
  4. Run npx patch-package imagemin-pngquant
  5. Commit the changes, including the patch

This will save the change that you make to the index.js file and apply it any time / anywhere that npm install or yarn is run in the project.

Diff (difference before and after)

	const promise = subprocess
		.then(result => result.stdout) // eslint-disable-line promise/prefer-await-to-then
		.catch(error => {
-			if (error.code === 99) {
+			if (error.exitCode === 99) {
				return input;
			}

Downgrading isn’t resolving this issue for me either

Are there any known workarounds yet? Right now as described previously not even downgrading fixes the issue anymore.