gatsbyjs/gatsby · error · Error

toFormat seems to be empty, we need a fileExtension to set i

Error message

toFormat seems to be empty, we need a fileExtension to set it.

What it means

In plugin-options.ts healOptions, the output format is taken from options.toFormat when set; otherwise it falls back to the source file's extension. If toFormat is empty AND no fileExtension can be determined (the source has no recognizable extension), the code cannot pick a target format and throws. Sharp requires an explicit output format (jpg, png, webp, avif) to encode.

Source

Thrown at packages/gatsby-plugin-sharp/src/plugin-options.ts:186

  defaultArgs = {}
): Partial<IGeneralArgs> & {
  quality: number
} & ITransformArgs => {
  const options = defaults({}, args, { quality }, defaultArgs, generalArgs)
  // @ts-ignore - parseInt as safeguard, expects string tho
  options.quality = parseInt(options.quality, 10)
  // @ts-ignore - parseInt as safeguard, expects string tho
  options.pngCompressionLevel = parseInt(options.pngCompressionLevel, 10)
  // @ts-ignore - parseInt as safeguard, expects string tho
  options.pngCompressionSpeed = parseInt(options.pngCompressionSpeed, 10)
  options.toFormat = options.toFormat.toLowerCase()
  options.toFormatBase64 = options.toFormatBase64?.toLowerCase()
  options.base64Width = options.base64Width || base64Width

  // when toFormat is not set we set it based on fileExtension
  if (options.toFormat === ``) {
    if (!fileExtension) {
      throw new Error(
        `toFormat seems to be empty, we need a fileExtension to set it.`
      )
    }
    options.toFormat = fileExtension.toLowerCase()

    if (fileExtension === `jpeg`) {
      options.toFormat = `jpg`
    }
  }

  // only set width to 400 if neither width nor height is passed
  if (options.width === undefined && options.height === undefined) {
    options.width = 400
  }
  if (options.width !== undefined) {
    // @ts-ignore - parseInt as safeguard, expects string tho
    options.width = parseInt(options.width, 10)
  }

View on GitHub (pinned to 8b06340921)

Solutions

  1. Set toFormat explicitly in the sharp options or in gatsby-plugin-sharp pluginOptions, e.g. sharpOptions: { toFormat: 'webp' }.
  2. Ensure the source file path ends with a recognized extension before processing.
  3. If fetching remote images, derive and append the extension from Content-Type in onCreateNode.

Example fix

// before
sharp({ file: '/tmp/img-9281' }) // no extension, no toFormat

// after
sharp({ file: '/tmp/img-9281', toFormat: 'webp' })
Defensive patterns

Strategy: validation

Validate before calling

function ensureToFormat(options, fileExtension) {
  if (!options.toFormat) {
    if (!fileExtension) {
      throw new Error('toFormat is empty and no fileExtension available');
    }
    options.toFormat = fileExtension.toLowerCase();
  }
  return options;
}

Type guard

function hasResolvableFormat(options, fileExtension) {
  return Boolean(options.toFormat) || Boolean(fileExtension);
}

Prevention

When it happens

Trigger: Processing an image whose path has no extension (e.g. a buffer or a tmp file named 'tmp-123') without setting toFormat; calling sharp APIs without format options on a file gatsby cannot introspect; a CMS delivering an image URL with a stripped extension.

Common situations: Remote images with no extension in the URL; files fetched into temp directories; misconfigured gatsby-plugin-sharp that loses the file extension during onCreateNode; custom transformers that rename files without extensions.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/d49db7a440511118. Report an issue: GitHub.