{"record":{"id":"2a59706d5d3c967b","repo":"NousResearch/hermes-agent","slug":"image-upload-did-not-return-a-path","errorCode":null,"errorMessage":"image upload did not return a path","messagePattern":"image upload did not return a path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"web/src/lib/chatImagePaste.ts","lineNumber":161,"sourceCode":"  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":143,"sourceCodeEnd":165,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/web/src/lib/chatImagePaste.ts#L143-L165","documentation":"The upload endpoint answered 2xx but the JSON body lacked a `path` field, so the client cannot hand a file path to the TUI's /image command. This is a contract violation between the dashboard client and the gateway's /api/chat/image-upload handler, not a transport failure.","triggerScenarios":"A 200 response from a proxy/health endpoint returning unrelated JSON, a gateway version whose handler returns a differently-named field (e.g. `file_path`), or a handler bug returning `{ok: true}` without the stored path.","commonSituations":"Version skew between built web assets and the running gateway (older/newer handler shape), a reverse proxy intercepting the route, or custom middleware rewriting response bodies.","solutions":["Confirm the gateway version matches the web build — rebuild/redeploy so client and server agree on the `{path}` contract.","Inspect the actual response body in the network tab to see what shape the server returned; fix the handler or the client to match.","Remove any proxy/interceptor that rewrites /api/chat/image-upload responses."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isUploadResult(v: unknown): v is ChatImageUploadResult {\n  return !!v && typeof v === 'object' && typeof (v as ChatImageUploadResult).path === 'string' && (v as ChatImageUploadResult).path.length > 0\n}","tryCatchPattern":"const raw: unknown = await res.json()\nif (!isUploadResult(raw)) {\n  throw new Error(`unexpected upload response shape: ${JSON.stringify(raw).slice(0, 200)}`)\n}","preventionTips":["Pin gateway and web-bundle versions together so the {path} contract holds.","Add an integration test asserting the endpoint returns {path} on success.","Don't put proxies or body-rewriting middleware in front of /api/chat/image-upload."],"tags":["api-contract","upload","image","version-skew"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}