{"record":{"id":"91c2e99895f805ef","repo":"janhq/jan","slug":"failed-to-resolve-ingested-attachment-id","errorCode":null,"errorMessage":"Failed to resolve ingested attachment id","messagePattern":"Failed to resolve ingested attachment id","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web-app/src/services/uploads/default.ts","lineNumber":30,"sourceCode":"    return { id: ulid() }\n  }\n\n  async ingestFileAttachment(threadId: string, attachment: Attachment): Promise<UploadResult> {\n    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')","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/web-app/src/services/uploads/default.ts#L12-L48","documentation":"Thrown by ingestFileAttachment when ingestAttachments resolved but the returned files array is empty or the first entry has no id. The backend accepted the call but produced no usable file reference - typically the document was silently rejected during indexing.","triggerScenarios":"res.files is not an array, is empty, or res.files[0].id is falsy after a successful (non-throwing) ingestAttachments call.","commonSituations":"Unsupported file format silently rejected by the indexer; backend bug returning an empty result; partial backend failure; file too large or deduplicated to nothing; malformed backend response.","solutions":["Check the RAG backend logs for why the file produced no chunks/id.","Verify the file type is supported and the file is non-empty.","Retry; if persistent, report with the file name and type."],"exampleFix":"// before: generic 'Failed to resolve ingested attachment id'\nif (!Array.isArray(files) || !files[0]?.id) throw new Error('Failed to resolve ingested attachment id')\n// after: name the file and hint at the likely cause\nif (!Array.isArray(files) || !files[0]?.id) {\n  throw new Error(`Ingestion of '${attachment.name}' produced no id; the backend may not support this file type`)\n}","handlingStrategy":"try-catch","validationCode":"function validateIngestResult(res: IngestAttachmentsResult): boolean {\n  return Array.isArray(res.files) && !!res.files[0]?.id\n}","typeGuard":"function hasIngestedId(res: unknown): res is { files: { id: string }[] } {\n  return Array.isArray((res as any)?.files) && !!((res as any).files[0]?.id)\n}","tryCatchPattern":"try {\n  await uploads.ingestFileAttachment(tid, att)\n} catch (e) {\n  if (/resolve ingested attachment id/.test(String((e as Error).message))) {\n    showFileFailed(att.name)\n  } else throw e\n}","preventionTips":["Validate supported file types before uploading.","Surface per-file failure to the user with the filename."],"tags":["rag","uploads","empty-result","backend","ingestion"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}