{"record":{"id":"0d30806c69d101d7","repo":"janhq/jan","slug":"rag-extension-does-not-support-project-level-inges","errorCode":null,"errorMessage":"RAG extension does not support project-level ingestion","messagePattern":"RAG extension does not support project-level ingestion","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"web-app/src/services/uploads/default.ts","lineNumber":36,"sourceCode":"    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":18,"sourceCodeEnd":51,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/web-app/src/services/uploads/default.ts#L18-L51","documentation":"Thrown when the RAG extension registered with the ExtensionManager exists but does not implement ingestAttachmentsForProject, so project-level ingestion is unsupported in this build/configuration. The service requires ext?.ingestAttachmentsForProject to be truthy.","triggerScenarios":"Calling ingestFileAttachmentForProject when the registered RAG extension only implements thread-level ingestAttachments (no project variant), or no RAG extension is registered at all.","commonSituations":"Running an older RAG extension that predates project-level ingestion; project upload feature shipped before the extension supporting it was deployed; extension build/version mismatch between web-app and the installed extension.","solutions":["Upgrade or replace the RAG extension with a version that implements ingestAttachmentsForProject","Fall back to thread-level ingestFileAttachment when project ingestion is unsupported","Feature-gate the project-upload UI on capability detection: !!ext?.ingestAttachmentsForProject"],"exampleFix":"// before\nawait uploads.ingestFileAttachmentForProject(projectId, att)\n// after\nconst ext = ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)\nconst result = ext?.ingestAttachmentsForProject\n  ? await uploads.ingestFileAttachmentForProject(projectId, att)\n  : await uploads.ingestFileAttachment(threadId, att)","handlingStrategy":"fallback","validationCode":"const supportsProjectIngest = (): boolean =>\n  !!ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)?.ingestAttachmentsForProject","typeGuard":"const supportsProjectIngestion = (ext: RAGExtension | undefined): ext is RAGExtension & { ingestAttachmentsForProject: NonNullable<RAGExtension['ingestAttachmentsForProject']> } =>\n  typeof ext?.ingestAttachmentsForProject === 'function'","tryCatchPattern":"try {\n  return await uploads.ingestFileAttachmentForProject(projectId, att)\n} catch (e) {\n  if (e instanceof Error && e.message.includes('project-level ingestion')) {\n    return uploads.ingestFileAttachment(threadId, att) // graceful fallback\n  }\n  throw e\n}","preventionTips":["Detect ingestAttachmentsForProject support before showing project-upload controls","Keep the RAG extension version aligned with the web-app's expected feature set","Define a documented fallback to thread-level ingestion when project ingestion is absent"],"tags":["extension","rag","unsupported-operation"],"backgroundTag":"operation-not-supported","analyzedSha":"7205d770c1e097c3daf35a911176410e93bc5564","analyzedAt":"2026-09-17T14:27:30.100Z","contentChangedAt":"2026-09-17T14:27:30.100Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}