janhq/jan · error · Error
No ID returned from image ingestion
Error message
No ID returned from image ingestion
What it means
After uploading an image for ingestion the code expects the response to include an id, which it writes back into the attachment state. If result.id is missing the upload is treated as failed: the error is thrown, caught, logged, and the in-progress attachment is removed from state.
Solutions
- Check the ingestion endpoint response body in devtools/network tab and confirm it contains id.
- Verify the frontend and backend ingestion API contract versions match.
- Validate the parsed response before consuming it and surface a clearer server error message.
- Retry the upload; transient gateway issues can return malformed empty bodies.
Example fix
// before
} else {
throw new Error('No ID returned from image ingestion')
}
// after
} else {
throw new Error(
`No ID returned from image ingestion: ${JSON.stringify(result).slice(0, 200)}`
)
} Defensive patterns
Strategy: validation
Validate before calling
const ingestResponse = await res.json()
if (!ingestResponse || typeof ingestResponse.id !== 'string' || !ingestResponse.id) {
throw new Error(`Image ingestion returned invalid response: ${JSON.stringify(ingestResponse)}`)
} Type guard
function hasIngestionId(r: unknown): r is { id: string } {
return typeof r === 'object' && r !== null && 'id' in r && typeof (r as { id: unknown }).id === 'string'
} Try / catch
try {
const result = await ingestImage(file)
if (!result?.id) throw new Error('No ID returned from image ingestion')
} catch (error) {
console.error('Failed to ingest image:', error)
toast.error('Image upload failed. Please try again.')
setAttachmentsForThread(attachmentsKey, prev => prev.filter(a => !matchImg(a)))
} Prevention
- Validate ingestion responses against a schema (zod) before consuming.
- Keep frontend/backend API contracts versioned and tested.
- Check network tab for HTML/empty bodies masquerading as 200 responses.
- Surface failed attachments to the user instead of silently removing them.
When it happens
Trigger: The image ingestion endpoint returns a 2xx response whose JSON body lacks an id field (e.g. older backend, wrong endpoint, error-shaped body with 200 status, or result being undefined after a failed JSON parse).
Common situations: Backend/API version drift where the ingestion response shape changed; a proxy returning an HTML error page with 200; attaching images while pointing the app at a misconfigured or stale server.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- API request failed with status
- Failed to fetch HuggingFace repository
- Failed to fetch models from
- Failed to fetch releases
- Failed to fetch repository files
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/5ebce1326fddc237.
Report an issue: GitHub.
Appendix: source
Thrown at web-app/src/containers/ChatInput.tsx:1384
const result = await serviceHub
.uploads()
.ingestImage(currentThreadId, img)
if (result?.id) {
setAttachmentsForThread(attachmentsKey, (prev) =>
prev.map((a) =>
matchImg(a)
? {
...a,
processing: false,
processed: true,
id: result.id,
}
: a
)
)
} else {
throw new Error('No ID returned from image ingestion')
}
} catch (error) {
console.error('Failed to ingest image:', error)
setAttachmentsForThread(attachmentsKey, (prev) =>
prev.filter((a) => !matchImg(a))
)
toast.error(`Failed to ingest ${img.name}`, {
description:
error instanceof Error ? error.message : String(error),
})
} finally {
setFileIngestProgress({
completed: i + 1,
total: ingestTotal,
})
}
}
} finally {View on GitHub (pinned to 7205d770c1)