janhq/jan · error · Error
ingestFileAttachmentForProject: attachment is not document
Error message
ingestFileAttachmentForProject: attachment is not document
What it means
Thrown by DefaultUploadsService.ingestFileAttachmentForProject when attachment.type !== 'document'. It is the project-level counterpart of error 168 - a contract guard ensuring only document attachments enter the project ingestion path.
Source
Thrown at web-app/src/services/uploads/default.ts:34
if (attachment.type !== 'document') throw new Error('ingestFileAttachment: attachment is not document')
const ext = ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)
if (!ext?.ingestAttachments) throw new Error('RAG extension not available')
const res: IngestAttachmentsResult = await ext.ingestAttachments(threadId, [
{ path: attachment.path!, name: attachment.name, type: attachment.fileType, size: attachment.size },
])
const files = res.files
if (Array.isArray(files) && files[0]?.id) {
return {
id: files[0].id,
size: typeof files[0].size === 'number' ? Number(files[0].size) : undefined,
chunkCount: typeof files[0].chunk_count === 'number' ? Number(files[0].chunk_count) : undefined,
}
}
throw new Error('Failed to resolve ingested attachment id')
}
async ingestFileAttachmentForProject(projectId: string, attachment: Attachment): Promise<UploadResult> {
if (attachment.type !== 'document') throw new Error('ingestFileAttachmentForProject: attachment is not document')
const ext = ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)
if (!ext?.ingestAttachmentsForProject) throw new Error('RAG extension does not support project-level ingestion')
const res: IngestAttachmentsResult = await ext.ingestAttachmentsForProject(projectId, [
{ path: attachment.path!, name: attachment.name, type: attachment.fileType, size: attachment.size },
])
const files = res.files
if (Array.isArray(files) && files[0]?.id) {
return {
id: files[0].id,
size: typeof files[0].size === 'number' ? Number(files[0].size) : undefined,
chunkCount: typeof files[0].chunk_count === 'number' ? Number(files[0].chunk_count) : undefined,
}
}
throw new Error('Failed to resolve ingested attachment id')
}
}
View on GitHub (pinned to fad3f12a14)
Solutions
- Route only document attachments to ingestFileAttachmentForProject.
- Dispatch by attachment.type from a single location.
Example fix
// before: project path receives any attachment
await uploads.ingestFileAttachmentForProject(pid, att)
// after: dispatch by type
if (att.type === 'document') await uploads.ingestFileAttachmentForProject(pid, att)
else throw new Error(`Unsupported attachment type for project: ${att.type}`) Defensive patterns
Strategy: validation
Validate before calling
if (attachment.type !== 'document') throw new Error('Skip non-document for project') Type guard
function isDocumentAttachment(a: Attachment): boolean { return a.type === 'document' } Prevention
- Centralize type-based dispatch for project uploads in one place.
- Use a discriminated union for Attachment to get compile-time safety on type.
When it happens
Trigger: ingestFileAttachmentForProject(projectId, attachment) is called with an attachment whose type field is not 'document' (e.g., an image or unknown type).
Common situations: Incorrect dispatch in the project-upload pipeline; an image attachment reaching the project document path; attachment type values changed during a refactor.
Related errors
- ingestImage: attachment is not image
- ingestFileAttachment: attachment is not document
- File '${f.name}' exceeds size limit (${f.size} bytes > ${max
- RAG extension does not support project-level ingestion
- Failed to ingest file
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/3375ceca98ac8282.
Report an issue: GitHub.