{"record":{"id":"139e8077e726e1db","repo":"immich-app/immich","slug":"await-response-text","errorCode":null,"errorMessage":"await response.text()","messagePattern":"await response\\.text\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/asset.ts","lineNumber":441,"sourceCode":"    try {\n      const stats = await stat(sidecarPath);\n      const sidecarData = new UploadFile(sidecarPath, stats.size);\n      formData.append('sidecarData', sidecarData);\n    } catch {\n      // noop\n    }\n  }\n\n  const response = await fetch(`${baseUrl}/assets`, {\n    method: 'post',\n    redirect: 'error',\n    headers: headers as Record<string, string>,\n    body: formData,\n    // eslint-disable-next-line unicorn/no-null\n    window: null,\n  });\n  if (response.status !== 200 && response.status !== 201) {\n    throw new Error(await response.text());\n  }\n\n  return response.json() as Promise<AssetMediaResponseDto>;\n};\n\nexport const findSidecar = (filepath: string): string | undefined => {\n  const assetPath = path.parse(filepath);\n  const noExtension = path.join(assetPath.dir, assetPath.name);\n\n  // XMP sidecars can come in two filename formats. For a photo named photo.ext, the filenames are photo.ext.xmp and photo.xmp\n  for (const sidecarPath of [`${noExtension}.xmp`, `${filepath}.xmp`]) {\n    if (existsSync(sidecarPath)) {\n      return sidecarPath;\n    }\n  }\n};\n\nexport const deleteFiles = async (uploaded: Asset[], duplicates: Asset[], options: UploadOptionsDto): Promise<void> => {","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/packages/cli/src/commands/asset.ts#L423-L459","documentation":"uploadFile performs the asset-media PUT via fetch-like ofetch; when the Immich server responds with any status other than 200/201, the raw body text is read and thrown as the Error message. The developer-facing message is therefore whatever the server returned (e.g. an HTML error page, a JSON problem body, or an empty string), not a structured error.","triggerScenarios":"The server returns 400 (bad upload payload/size limits), 401/403 (bad or missing API key), 413 (file too large for the reverse proxy, e.g. nginx client_max_body_size), or 5xx (server crash/storage full) during `immich upload`.","commonSituations":"Expired or wrong IMMICH_API_KEY, reverse proxy (nginx/Traefik/Cloudflare) rejecting large video files with 413, Immich server restarting mid-upload, or uploading to the wrong base URL hitting an auth/HTML page.","solutions":["Read the thrown message: it contains the server's response body, which usually names the real cause (401 => fix IMMICH_API_KEY, 413 => raise client_max_body_size).","For 413 behind nginx, set client_max_body_size (e.g. 50000M) and restart the proxy.","Verify the server URL and API key with `immich server-info`.","Retry large uploads on a stable connection; check Immich server logs for the corresponding request error."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const info = await getServerInfo(); // verifies API key + URL before big uploads\nif (!info) throw new Error('check IMMICH_INSTANCE_URL / IMMICH_API_KEY');","typeGuard":null,"tryCatchPattern":"try {\n  await uploadFile(filepath, stats, options);\n} catch (err) {\n  const msg = String(err);\n  if (msg.includes('401') || msg.toLowerCase().includes('unauthorized')) fixApiKeyAndRetry();\n  else if (/413|too large/i.test(msg)) console.error('raise client_max_body_size on the reverse proxy');\n  else throw err;\n}","preventionTips":["Call server-info first to validate credentials and URL","Configure reverse proxy client_max_body_size for large videos","Retry uploads with backoff for transient 5xx"],"tags":["http","upload","network","cli"],"backgroundTag":"http-error-response","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}