gatsbyjs/gatsby · warning
Could not parse file extension from Shopify image URL: ${url
Error message
Could not parse file extension from Shopify image URL: ${url} What it means
parseImageExtension splits a Shopify image URL on `?` then looks for the last `.` in the basename. If there is no dot, the URL has no detectable file extension and the function throws. The plugin uses the extension to decide whether to download the image as a local file node (gif is excluded by the caller). A URL with no extension means the helper cannot make that decision.
Source
Thrown at packages/gatsby-source-shopify/src/helpers.ts:148
createNode,
createNodeId,
parentNodeId: node.id,
})
image.localFile___NODE = fileNode.id
}
}
}
}
export function parseImageExtension(url: string): string {
const basename = url.split(`?`)[0]
const dot = basename.lastIndexOf(`.`)
if (dot !== -1) {
return basename.slice(dot + 1)
} else {
throw new Error(
`Could not parse file extension from Shopify image URL: ${url}`
)
}
}
View on GitHub (pinned to 8b06340921)
Solutions
- Wrap the call in try/catch and skip images whose extension cannot be parsed (do not let one bad URL abort sourcing).
- Pre-filter: only call createRemoteFileNode when the URL contains a dot after the query split.
- Patch upstream data so originalSrc always carries a real extension.
- If SVGs are involved, ensure the URL retains the .svg suffix before it reaches this helper.
Example fix
// before
if (image && parseImageExtension(image.originalSrc) !== `gif`) {
await createRemoteFileNode({ url: image.originalSrc, ... })
}
// after
try {
if (image && parseImageExtension(image.originalSrc) !== `gif`) {
await createRemoteFileNode({ url: image.originalSrc, ... })
}
} catch (e) {
reporter.warn(`Skipping image with unparseable extension: ${image?.originalSrc}`)
} Defensive patterns
Strategy: try-catch
Validate before calling
function safeImageExtension(url) {
const dot = url.split('?')[0].lastIndexOf('.')
return dot === -1 ? null : url.split('?')[0].slice(dot + 1)
} Type guard
const hasExtension = (url) => url.split('?')[0].includes('.') Try / catch
let ext
try { ext = parseImageExtension(url) } catch (e) { reporter.warn(`Skipping image (no extension): ${url}`); continue } Prevention
- Filter out extensionless image URLs before calling parseImageExtension
- Validate upstream Shopify image data quality
- Wrap the call so one bad URL cannot abort the whole build
When it happens
Trigger: Shopify returns an image URL with no extension (some CDN/S3-style URLs or SVGs served without extension); URL is a base64-like or signature URL where the dot is stripped; URL is malformed/empty; the originalSrc field is a placeholder that lacks an extension.
Common situations: Shopify storefront serving newly uploaded images where the CDN URL omits the extension; custom image transforms returning extensionless URLs; third-party app replacing Shopify image URLs; testing against fixtures with malformed image data.
Related errors
- The "layout" argument is required for "${source.url}"
- Either the "width" or "height" argument is required f
- The provided width of "${width}" is incorrect. Dimensions sh
- The provided height of "${height}" is incorrect. Dimensions
- Unknown format "${args.format}" was given to resize ${source
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/2ec6d55842a60f5f.
Report an issue: GitHub.