{"record":{"id":"e99a1610842ff150","repo":"janhq/jan","slug":"failed-to-ingest-file","errorCode":null,"errorMessage":"Failed to ingest file","messagePattern":"Failed to ingest file","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web-app/src/stores/project-uploads-store.ts","lineNumber":77,"sourceCode":"        currentFileName = att.name\n\n        set((s) => {\n          const existing = s.progress[projectId]\n          if (!existing) return s\n          return {\n            progress: {\n              ...s.progress,\n              [projectId]: {\n                ...existing,\n                current: i,\n                currentFileName: att.name,\n              },\n            },\n          }\n        })\n\n        const result = await ingestFn(projectId, att)\n        if (!result.id) throw new Error('Failed to ingest file')\n\n        set((s) => {\n          const existing = s.progress[projectId]\n          const nextTick = (s.completedTick[projectId] ?? 0) + 1\n          return {\n            progress: existing\n              ? {\n                  ...s.progress,\n                  [projectId]: { ...existing, current: i + 1 },\n                }\n              : s.progress,\n            completedTick: { ...s.completedTick, [projectId]: nextTick },\n          }\n        })\n      }\n      handlers.onSuccess()\n    } catch (error) {\n      handlers.onError(error, currentFileName)","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/web-app/src/stores/project-uploads-store.ts#L59-L95","documentation":"Thrown by the project-uploads zustand store during its ingest loop when ingestFn(projectId, att) resolved but result.id is falsy. It stops the batch and reports the failing file via handlers.onError(error, currentFileName). It is the store-level wrapper over upstream upload-service failures (e.g., cascading from errors 172/173).","triggerScenarios":"For some attachment in the batch, ingestFn returned a result whose id is undefined/null/empty-string. The store throws 'Failed to ingest file', which is caught by the surrounding try and routed to handlers.onError with the current file name.","commonSituations":"Underlying upload service (DefaultUploadsService.ingestFileAttachmentForProject) returned no id; project RAG backend silently rejected the file; integration returned a malformed result object.","solutions":["Inspect the underlying ingestFn - usually ingestFileAttachmentForProject - for why no id came back (see errors 172/173).","Check the RAG backend logs for the specific file named in onError.","Validate file type/size before adding files to the batch."],"exampleFix":"// before: a single missing id aborts the whole batch\nconst result = await ingestFn(projectId, att)\nif (!result.id) throw new Error('Failed to ingest file')\n// after: collect per-file failures and continue\nconst result = await ingestFn(projectId, att)\nif (!result.id) { failed.push(att.name); continue }","handlingStrategy":"try-catch","validationCode":"function hasIngestId(r: { id?: string } | null | undefined): boolean { return !!r?.id }","typeGuard":"function isIngestSuccess(r: unknown): r is { id: string } {\n  return typeof (r as any)?.id === 'string' && !!((r as any).id)\n}","tryCatchPattern":"await useProjectUploads.getState().ingest(pid, attachments, ingestFn, {\n  onSuccess: () => refreshFiles(pid),\n  onError: (e, fileName) => toast.error(`Failed to ingest ${fileName ?? 'file'}`),\n})","preventionTips":["Provide a clear onError that names the failing file.","Consider per-file failure collection instead of aborting the whole batch.","Pre-validate attachments before starting the batch."],"tags":["store","uploads","batch","project","zustand"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}