{"record":{"id":"3375ceca98ac8282","repo":"janhq/jan","slug":"ingestfileattachmentforproject-attachment-is-not","errorCode":null,"errorMessage":"ingestFileAttachmentForProject: attachment is not document","messagePattern":"ingestFileAttachmentForProject: attachment is not document","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web-app/src/services/uploads/default.ts","lineNumber":34,"sourceCode":"    if (attachment.type !== 'document') throw new Error('ingestFileAttachment: attachment is not document')\n    const ext = ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)\n    if (!ext?.ingestAttachments) throw new Error('RAG extension not available')\n    const res: IngestAttachmentsResult = await ext.ingestAttachments(threadId, [\n      { path: attachment.path!, name: attachment.name, type: attachment.fileType, size: attachment.size },\n    ])\n    const files = res.files\n    if (Array.isArray(files) && files[0]?.id) {\n      return {\n        id: files[0].id,\n        size: typeof files[0].size === 'number' ? Number(files[0].size) : undefined,\n        chunkCount: typeof files[0].chunk_count === 'number' ? Number(files[0].chunk_count) : undefined,\n      }\n    }\n    throw new Error('Failed to resolve ingested attachment id')\n  }\n\n  async ingestFileAttachmentForProject(projectId: string, attachment: Attachment): Promise<UploadResult> {\n    if (attachment.type !== 'document') throw new Error('ingestFileAttachmentForProject: attachment is not document')\n    const ext = ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)\n    if (!ext?.ingestAttachmentsForProject) throw new Error('RAG extension does not support project-level ingestion')\n    const res: IngestAttachmentsResult = await ext.ingestAttachmentsForProject(projectId, [\n      { path: attachment.path!, name: attachment.name, type: attachment.fileType, size: attachment.size },\n    ])\n    const files = res.files\n    if (Array.isArray(files) && files[0]?.id) {\n      return {\n        id: files[0].id,\n        size: typeof files[0].size === 'number' ? Number(files[0].size) : undefined,\n        chunkCount: typeof files[0].chunk_count === 'number' ? Number(files[0].chunk_count) : undefined,\n      }\n    }\n    throw new Error('Failed to resolve ingested attachment id')\n  }\n}\n","sourceCodeStart":16,"sourceCodeEnd":51,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/web-app/src/services/uploads/default.ts#L16-L51","documentation":"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.","triggerScenarios":"ingestFileAttachmentForProject(projectId, attachment) is called with an attachment whose type field is not 'document' (e.g., an image or unknown type).","commonSituations":"Incorrect dispatch in the project-upload pipeline; an image attachment reaching the project document path; attachment type values changed during a refactor.","solutions":["Route only document attachments to ingestFileAttachmentForProject.","Dispatch by attachment.type from a single location."],"exampleFix":"// before: project path receives any attachment\nawait uploads.ingestFileAttachmentForProject(pid, att)\n// after: dispatch by type\nif (att.type === 'document') await uploads.ingestFileAttachmentForProject(pid, att)\nelse throw new Error(`Unsupported attachment type for project: ${att.type}`)","handlingStrategy":"validation","validationCode":"if (attachment.type !== 'document') throw new Error('Skip non-document for project')","typeGuard":"function isDocumentAttachment(a: Attachment): boolean { return a.type === 'document' }","tryCatchPattern":null,"preventionTips":["Centralize type-based dispatch for project uploads in one place.","Use a discriminated union for Attachment to get compile-time safety on type."],"tags":["validation","attachment","type-mismatch","uploads","project","programming-bug"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}