{"record":{"id":"187bd343c81a2378","repo":"NousResearch/hermes-agent","slug":"text-http-res-status","errorCode":null,"errorMessage":"text || HTTP ${res.status}","messagePattern":"text \\|\\| HTTP (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"web/src/lib/chatImagePaste.ts","lineNumber":156,"sourceCode":"  const file =\n    blob instanceof File\n      ? blob\n      : new File([blob], filename, { type: mime });\n\n  const dataUrl = await fileToDataUrl(file);\n  const qs = profile ? `?profile=${encodeURIComponent(profile)}` : \"\";\n  const res = await authedFetch(`/api/chat/image-upload${qs}`, {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application/json\" },\n    body: JSON.stringify({\n      data_url: dataUrl,\n      filename,\n    }),\n  });\n\n  if (!res.ok) {\n    const text = await res.text().catch(() => res.statusText);\n    throw new Error(text || `HTTP ${res.status}`);\n  }\n\n  const uploaded = (await res.json()) as ChatImageUploadResult;\n  if (!uploaded?.path) {\n    throw new Error(\"image upload did not return a path\");\n  }\n  return uploaded;\n}\n","sourceCodeStart":138,"sourceCodeEnd":165,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/web/src/lib/chatImagePaste.ts#L138-L165","documentation":"The image upload POST to /api/chat/image-upload returned a non-OK HTTP status. The error prefers the server's response body text (which usually carries the backend's own error message) and falls back to `HTTP <status>` only when the body is empty. This is the same pattern as the dashboard's generic authedFetch error, applied to the chat image endpoint.","triggerScenarios":"Uploading a data_url whose base64 is corrupt or whose mime is disallowed (400), uploading when the session expired (401), hitting a server-side body-size limit (413), or the gateway erroring while writing the upload to disk (500).","commonSituations":"Session cookie expired between page load and paste; reverse proxy (nginx/caddy) with a smaller client_max_body_size than the dashboard's limit; disk-full or permission errors in the gateway's upload directory.","solutions":["Read the server text in the error message — it usually names the exact backend cause (invalid data URL, payload too large, auth required).","For 401: reload the dashboard to refresh auth, then paste again.","For 413: raise the proxy's request body limit or send a smaller image (see the max-MB error).","For 500: check gateway logs for the write failure (permissions/disk) in the upload target directory."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const { path } = await uploadChatImage(blob, profile)\n} catch (err) {\n  const msg = String(err)\n  if (msg.startsWith('401') || msg.startsWith('403')) { location.reload(); return }\n  if (msg.startsWith('413')) { toast('Image too large for the server'); return }\n  toast(`Upload failed: ${msg}`)\n}","preventionTips":["Surface the server-provided body text verbatim — it names the real cause.","Keep proxy body limits aligned with the client-side MAX_IMAGE_BYTES.","Handle auth expiry (401) by reloading rather than retrying the same request."],"tags":["http","upload","image","dashboard"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}