{"record":{"id":"8c7989c800791297","repo":"payloadcms/payload","slug":"fetch-failed-with-status-response-status","errorCode":null,"errorMessage":"Fetch failed with status: ${response.status}","messagePattern":"Fetch failed with status: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ui/src/elements/Upload/useUploadFromUrl.ts","lineNumber":89,"sourceCode":"        return false\n      }\n\n      const fileName = getFileNameFromUrl({ overrideFileName: uploadControlFileName, url })\n      onFileFetched(new File([blob], fileName, { type: blob.type }))\n      setUploadStatus('idle')\n      closeModal(pasteURLDrawerSlug)\n      setFileUrl('')\n      return true\n    },\n    [closeModal, onFileFetched, setUploadStatus, t, uploadConfig, uploadControlFileName],\n  )\n\n  const fetchFileFromClient = useCallback(\n    async (url: string): Promise<boolean> => {\n      const response = await fetch(url)\n\n      if (!response.ok) {\n        throw new Error(`Fetch failed with status: ${response.status}`)\n      }\n\n      const blob = await response.blob()\n      return acceptFetchedBlob({ blob, url })\n    },\n    [acceptFetchedBlob],\n  )\n\n  const fetchFileFromServerProxy = useCallback(\n    async (url: string): Promise<boolean> => {\n      const pasteURL: `/${string}` = `/${collectionSlug}/paste-url${id ? `/${id}?` : '?'}src=${encodeURIComponent(url)}`\n      const response = await fetch(formatAdminURL({ apiRoute: api, path: pasteURL }))\n\n      if (!response.ok) {\n        throw new Error(`Fetch failed with status: ${response.status}`)\n      }\n\n      const blob = await response.blob()","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/ui/src/elements/Upload/useUploadFromUrl.ts#L71-L107","documentation":"A plain Error thrown in useUploadFromUrl's fetchFileFromClient when a direct browser fetch of the user-pasted URL returns non-ok. This is the client-side branch (the alternative to the server proxy) for the 'upload from URL' feature.","triggerScenarios":"The user pastes a URL; the browser fetches it directly and the remote returns non-2xx (404, 403) or the fetch is blocked by CORS so response.ok is false / the fetch rejects.","commonSituations":"CORS policy on the remote host blocks cross-origin reads from the admin domain; the URL is wrong/expired (404); the remote requires auth/Referer the browser can't supply; mixed-content (https admin fetching http URL).","solutions":["Use the server-proxy path (fetchFileFromServerProxy) instead of the client fetch when CORS blocks direct reads.","Ensure the remote host sends permissive CORS headers (Access-Control-Allow-Origin) for the admin origin.","Validate the URL is reachable and HTTPS before fetching.","Catch the error and fall back to the server proxy automatically."],"exampleFix":"// before\nconst fetchFileFromClient = useCallback(async (url: string) => {\n  const response = await fetch(url)\n  if (!response.ok) throw new Error(`Fetch failed with status: ${response.status}`)\n  const blob = await response.blob()\n  return acceptFetchedBlob({ blob, url })\n}, [acceptFetchedBlob])\n\n// after — fall back to server proxy on client failure\nconst fetchFileFromClient = useCallback(async (url: string) => {\n  try {\n    const response = await fetch(url)\n    if (!response.ok) throw new Error(`Fetch failed with status: ${response.status}`)\n    const blob = await response.blob()\n    return acceptFetchedBlob({ blob, url })\n  } catch {\n    return fetchFileFromServerProxy(url)\n  }\n}, [acceptFetchedBlob, fetchFileFromServerProxy])","handlingStrategy":"fallback","validationCode":"async function isDirectlyFetchable(url: string): Promise<boolean> {\n  try {\n    const res = await fetch(url, { method: 'HEAD' })\n    return res.ok\n  } catch {\n    return false\n  }\n}\n\nif (!(await isDirectlyFetchable(url))) {\n  return fetchFileFromServerProxy(url)\n}","typeGuard":"function isClientFetchFailure(err: unknown): err is Error {\n  return err instanceof Error && /Fetch failed with status/i.test(err.message)\n}","tryCatchPattern":"try {\n  return await fetchFileFromClient(url)\n} catch (err) {\n  if (isClientFetchFailure(err)) {\n    return fetchFileFromServerProxy(url) // CORS-safe fallback\n  }\n  throw err\n}","preventionTips":["Prefer the server proxy for URLs that may block cross-origin reads.","Validate the URL scheme is HTTPS to avoid mixed-content blocks.","Fall back to the server proxy automatically on client-fetch failure."],"tags":["ui","upload","client","network","cors","from-url"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}