sharp: Intermittent Error: Input file has corrupt header: glib: SVG has no elements

Getting these errors periodically (~10% of the time) when I do a gulp build to produce several pngs from an SVG. The parameters and input file are exactly the same every time. Not sure how to track this one down. Here’s a copy of the SVG. It appears to be OK.

Here’s the code (didn’t get around to adding the error handling but none of the parameters are changing either).

gulp.task('build:icons-sharp', async() => {
  const render = renderConfig => {
    const { image, width } = renderConfig; // required properties

    if(!image || !width) throw new Error('Gulp error in \'build:icons-sharp\': The parameters image and width are required.');

    const clone = image.clone(); // Do not change original

    let { height, name, scale, background } = renderConfig; // optional properties

    scale = scale || 100;
    height = height || width; // assume a square if height not provided
    // If name is provided, assume dist/client, else dist/client/assets/images
    name = name ? `./${paths.dist}/${clientPath}/${name}` : `./${paths.dist}/${clientPath}/assets/images/logo-${width}x${height}.png`;

    // Calculate width & height of scaled square logo (rounded)
    const smallerLength = Math.min(width, height);
    const logoLength = Math.round(smallerLength * scale / 100);

    // Calculate padding to center scaled logo within width x height box
    const top = Math.floor((height - logoLength) / 2); // if fractional, smaller padding at the top
    const bottom = Math.ceil((height - logoLength) / 2);
    const left = Math.floor((width - logoLength) / 2); // if fractional, smaller padding on left
    const right = Math.ceil((width - logoLength) / 2);

    clone
      .resize(logoLength)
      .extend({
        top,
        bottom,
        left,
        right,
        background: background ? background : { r: 0, g: 0, b: 0, alpha: 0 }
      });

    if(background) clone.flatten({ background });

    return clone.toFile(name);
  };

  const image = sharp(paths.client.svgIcon);
  const themeBackground = { background: '#5f4884' }; // Lavender when a background is needed
  const android = { }; // Android devices use the defaults
  const iOS = { ...themeBackground, scale: 95 };
  const edge = { ...themeBackground, scale: 70 };
  const startup = { background: '#fff', scale: 75 };
  const schema = { background: '#fff' };

  return await Promise.all([
    render({ image, width: 128, ...edge }), // Edge 70x70
    render({ image, width: 180, name: 'apple-touch-icon.png', ...iOS }), // iOS
    render({ image, width: 192, ...android }), // Android
    render({ image, width: 270, ...edge }), // Edge 150x150
    render({ image, width: 512, ...android }), // Android
    render({ image, width: 558, height: 270, ...edge }), // Edge 310x150
    render({ image, width: 558, ...edge }), // Edge 310x310
    render({ image, width: 1024, ...schema }), // Schema.org logo
    render({ image, width: 1536, height: 2048, ...startup }), // iOS startup logo - iPad Air A1475 portrait
    render({ image, width: 2048, height: 1536, ...startup }), // iOS startup logo - iPad Air A1475 portrait
    render({ image, width: 828, height: 1792, ...startup }), // iOS startup logo - iPhone XR portrait
    render({ image, width: 1792, height: 828, ...startup }), // iOS startup logo - iPhone XR landscape
    render({ image, width: 1125, height: 2436, ...startup }), // iOS startup logo - iPhone X/XS portrait
    render({ image, width: 2436, height: 1125, ...startup }), // iOS startup logo - iPhone X/XS landscape
    render({ image, width: 1668, height: 2224, ...startup }), // iOS startup logo - 10.5 iPad Pro portrait
    render({ image, width: 2224, height: 1668, ...startup }), // iOS startup logo - 10.5 iPad Pro landscape
    render({ image, width: 2048, height: 2732, ...startup }), // iOS startup logo - 12.9 iPad Pro portrait
    render({ image, width: 2732, height: 2048, ...startup }), // iOS startup logo - 12.9 iPad Pro landscape
    render({ image, width: 1242, height: 2688, ...startup }), // iOS startup logo - iPhone XS Max portrait
    render({ image, width: 2688, height: 1242, ...startup }) // iOS startup logo - iPhone XS Max landscape
  ]);
});

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 7
  • Comments: 23 (9 by maintainers)

Commits related to this issue

Most upvoted comments

I’m having similar problems, and was unfortunately unable to install brew dependencies on our build servers. I managed to fix the issue by “warming up” the library by running something like this before performing any actual SVG image operations

function warmupSharp(sharp) {
  return sharp(
    Buffer.from(
      `<svg xmlns="http://www.w3.org/2000/svg"><rect width="1" height="1" /></svg>`,
      'utf-8'
    )
  )
    .metadata()
    .then(() => sharp, () => sharp);
}

Apparently the error is only thrown on the first run of the library, regardless of if it fails. So ignoring any first error with a throwaway operation like this seems to make all subsequent run nicely.

Marvellous, thanks for confirming. Let’s track the libxml “upgrade” at https://github.com/lovell/package-libvips-darwin/issues/4