{"record":{"id":"ec90a754651d88c8","repo":"gatsbyjs/gatsby","slug":"remotefilenode-does-not-have-a-mimetype-the-field","errorCode":null,"errorMessage":"RemoteFileNode does not have a mimeType. The field is required.","messagePattern":"RemoteFileNode does not have a mimeType\\. The field is required\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/gatsby-plugin-utils/src/polyfill-remote-file/types.ts","lineNumber":89,"sourceCode":"\nexport type WidthOrHeight =\n  | { width: number; height: number }\n  | { width: number; height?: never }\n  | { width?: never; height: number }\n\nexport type CalculateImageSizesArgs = {\n  fit: ImageFit\n  layout: ImageLayout\n  outputPixelDensities: Array<number>\n  breakpoints?: Array<number>\n  aspectRatio?: number\n} & WidthOrHeight\n\nexport function isImage(node: {\n  mimeType: IRemoteFileNode[\"mimeType\"]\n}): node is IRemoteImageNode {\n  if (!node.mimeType) {\n    throw new Error(\n      `RemoteFileNode does not have a mimeType. The field is required.`\n    )\n  }\n\n  return node.mimeType.startsWith(`image/`) && node.mimeType !== `image/svg+xml`\n}\n\nexport type ImageCdnTransformArgs = WidthOrHeight & {\n  format: string\n  cropFocus?: ImageCropFocus | Array<ImageCropFocus>\n  quality: number\n}\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ntype CdnSourceImage = {\n  url: string\n  mimeType: string\n  filename: string","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-plugin-utils/src/polyfill-remote-file/types.ts#L71-L107","documentation":"Thrown by isImage() in polyfill-remote-file/types when a RemoteFileNode passed to an image resolver has no mimeType field. The function needs mimeType to determine if the file is an image (starts with 'image/' and is not SVG). A missing mimeType means the source plugin did not populate file metadata.","triggerScenarios":"node.mimeType is undefined/null/falsy when isImage(node) is called; the guard throws before the image check because mimeType is a prerequisite.","commonSituations":"A source plugin created a RemoteFileNode without fetching/storing mimeType, the content CDN did not return a content-type header, or a custom file creation bypassed the normal metadata enrichment.","solutions":["Ensure the source plugin populates mimeType when creating remote file nodes (fetch content-type from the remote response).","If using gatsby-source-filesystem or a CDN source, verify the remote server returns a valid Content-Type header.","Manually set mimeType on the node before it reaches the image resolver if the source cannot provide it.","Filter nodes to only pass those with a mimeType to image resolvers."],"exampleFix":"// before\ncreateNode({ ...fileData, internal: { type: 'File' } })\n// after\ncreateNode({ ...fileData, mimeType: response.headers['content-type'], internal: { type: 'File' } })","handlingStrategy":"type-guard","validationCode":"// Check mimeType before passing node to image resolvers\nif (!node.mimeType) {\n  throw new Error(`File node ${node.id} is missing mimeType — cannot use as image`)\n}","typeGuard":"function hasMimeType(node: { mimeType?: string }): node is { mimeType: string } {\n  return typeof node.mimeType === 'string' && node.mimeType.length > 0\n}\n\n// usage: if (hasMimeType(node)) { isImage(node) }","tryCatchPattern":"try {\n  if (isImage(node)) { /* process image */ }\n} catch (e) {\n  if (e.message.includes('mimeType')) {\n    // skip this node or fetch its mimeType first\n  } else throw e\n}","preventionTips":["Ensure source plugins fetch and store mimeType from the remote Content-Type header.","Filter nodes by mimeType presence before passing to image resolvers.","Add a schema customization that makes mimeType non-nullable on File nodes used as images."],"tags":["gatsby","image","validation","mimetype","file-node","source-plugin"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}