{"record":{"id":"f7bb8aa2113b7904","repo":"linshenkx/prompt-optimizer","slug":"failed-to-fetch-image-source-response-status","errorCode":null,"errorMessage":"Failed to fetch image source: ${response.status}","messagePattern":"Failed to fetch image source: (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/ui/src/utils/image-download.ts","lineNumber":179,"sourceCode":"  const urlApi = options.urlApi || URL\n\n  if (src.match(DATA_URL_PATTERN)) {\n    downloadBlob(dataUrlToBlob(src), filename, urlApi)\n    return true\n  }\n\n  if (src.match(BLOB_URL_PATTERN)) {\n    triggerAnchorDownload(src, filename)\n    return true\n  }\n\n  if (src.match(HTTP_URL_PATTERN)) {\n    const fetchImpl = options.fetchImpl || globalThis.fetch\n    if (typeof fetchImpl === 'function') {\n      try {\n        const response = await fetchImpl(src)\n        if (!response.ok) {\n          throw new Error(`Failed to fetch image source: ${response.status}`)\n        }\n        const blob = await response.blob()\n        downloadBlob(blob, filename, urlApi)\n        return true\n      } catch {\n        triggerAnchorDownload(src, filename)\n        return true\n      }\n    }\n  }\n\n  triggerAnchorDownload(src, filename)\n  return true\n}\n","sourceCodeStart":161,"sourceCodeEnd":194,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/utils/image-download.ts#L161-L194","documentation":"Thrown by downloadImageSource when fetching an image over HTTP(S) returns a non-ok response status. The function attempts to download the image bytes via fetch so it can trigger a blob download, and any response with response.ok === false (4xx/5xx) raises this error before the blob conversion. Note the surrounding catch swallows it and falls back to an anchor download, so it mainly surfaces when fetchImpl itself is missing or the fallback also fails.","triggerScenarios":"Calling downloadImageSource with a src matching an HTTP(S) URL where the server returns 403 (hotlink protection), 404, 401, or 5xx; passing a custom options.fetchImpl that returns non-ok responses; CORS-blocked responses surfaced as network errors.","commonSituations":"Hotlinked images protected by Referer/Origin checks returning 403; expired or signed CDN URLs returning 404/410; authenticated image endpoints requiring headers not passed through; environments without fetch causing anchor fallback.","solutions":["Verify the image URL directly (curl -I) and confirm it returns 200 without auth headers","If the endpoint requires auth or custom headers, pass an options.fetchImpl that adds them","Handle 403 hotlink protection by proxying the image through your own server or using a referrerPolicy-capable fetch","Rely on the built-in anchor-download fallback or implement your own fallback when the blob path fails"],"exampleFix":"// before\nawait downloadImageSource('https://cdn.example.com/img.png', 'img.png')\n// after - supply an authenticated fetch implementation\nawait downloadImageSource('https://cdn.example.com/img.png', 'img.png', {\n  fetchImpl: (input, init) => fetch(input, {\n    ...init,\n    headers: { ...init?.headers, Authorization: `Bearer ${token}` },\n  }),\n})","handlingStrategy":"fallback","validationCode":"const canFetchImage = async (src: string): Promise<boolean> => {\n  try {\n    const head = await fetch(src, { method: 'HEAD' })\n    return head.ok\n  } catch {\n    return false\n  }\n}","typeGuard":"const isHttpUrl = (src: string): boolean => /^https?:\\/\\//i.test(src)","tryCatchPattern":"try {\n  await downloadImageSource(src, filename)\n} catch {\n  // library already falls back to anchor download; add your own fallback (open in new tab, proxy) here\n  window.open(src, '_blank')\n}","preventionTips":["Pre-download check with HEAD request for user-supplied URLs","Pass an authenticated fetchImpl for private image endpoints","Provide server-side proxy for hotlink-protected images"],"tags":["image-download","http-status","fetch","cors"],"backgroundTag":"http-request-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}