{"record":{"id":"a839c3801c52180a","repo":"gatsbyjs/gatsby","slug":"generateimagesource-must-be-a-function","errorCode":null,"errorMessage":"generateImageSource must be a function","messagePattern":"generateImageSource must be a function","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/gatsby-plugin-image/src/image-utils.ts","lineNumber":245,"sourceCode":"    layout,\n    fit,\n    options,\n    width,\n    height,\n    filename,\n    reporter = { warn },\n    backgroundColor,\n    placeholderURL,\n  } = args\n\n  if (!pluginName) {\n    reporter.warn(\n      `[gatsby-plugin-image] \"generateImageData\" was not passed a plugin name`\n    )\n  }\n\n  if (typeof generateImageSource !== `function`) {\n    throw new Error(`generateImageSource must be a function`)\n  }\n\n  if (!sourceMetadata || (!sourceMetadata.width && !sourceMetadata.height)) {\n    // No metadata means we let the CDN handle max size etc, aspect ratio etc\n    sourceMetadata = {\n      width,\n      height,\n      format: sourceMetadata?.format || formatFromFilename(filename) || `auto`,\n    }\n  } else if (!sourceMetadata.format) {\n    sourceMetadata.format = formatFromFilename(filename)\n  }\n\n  const formats = new Set<ImageFormat>(args.formats)\n\n  if (formats.size === 0 || formats.has(`auto`) || formats.has(``)) {\n    formats.delete(`auto`)\n    formats.delete(``)","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-plugin-image/src/image-utils.ts#L227-L263","documentation":"Thrown by generateImageData in gatsby-plugin-image's image-utils when the `generateImageSource` argument is not a function. generateImageSource is the per-plugin hook that produces per-format image source descriptors; without it the pipeline cannot create any image data, so the call is rejected before any processing.","triggerScenarios":"Calling generateImageData({ ...args }) without supplying generateImageSource, or supplying it as a string/object/undefined. Typically happens when authoring a custom image CDN/plugin integration and forgetting to implement the hook, or when spreading an args object that omits it.","commonSituations":"Writing a new gatsby-plugin-image-compatible plugin and missing the generateImageSource export; passing the wrong destructured arg name; partial refactor that renamed the field; consuming an args object built upstream that dropped the function.","solutions":["Pass a function for generateImageSource that returns { [format]: { src, width, height, ... } } per requested format/width.","Verify the args object you pass to generateImageData includes generateImageSource (typeof === 'function').","Mirror the signature from gatsby-plugin-sharp or the official plugin-image CDN helpers."],"exampleFix":"// before\nawait generateImageData({ filename, sourceMetadata, layout })\n// after\nawait generateImageData({\n  filename,\n  sourceMetadata,\n  layout,\n  generateImageSource: ({ filename, width, height, format }) => ({ [format]: { src: `${filename}?w=${width}`, width, height } }),\n})","handlingStrategy":"type-guard","validationCode":"if (typeof args.generateImageSource !== 'function') {\n  throw new Error('generateImageSource required')\n}","typeGuard":"const hasGenerateImageSource = (a: any): a is { generateImageSource: Function } =>\n  !!a && typeof a.generateImageSource === 'function'","tryCatchPattern":null,"preventionTips":["Always pass a generateImageSource function to generateImageData.","Mirror the signature from gatsby-plugin-sharp.","Unit-test the args shape before integration."],"tags":["gatsby-plugin-image","plugin-api","validation","typescript"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}