janhq/jan · error
RAG extension not available
Error message
RAG extension not available
What it means
Thrown when the RAG extension is not registered with the ExtensionManager or it does not expose ingestAttachments. The service relies on ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG) and requires both the extension object and its ingestAttachments method.
Solutions
- Ensure the RAG extension is installed and registered with the ExtensionManager before any ingestion call
- Verify the @janhq/core version's RAGExtension still declares ingestAttachments and update the extension implementation accordingly
- Check registration order — extensions must be registered before uploads are triggered (e.g. gate the upload UI until extensions are ready)
Example fix
// before
const ext = ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)
await uploads.ingestFileAttachment(threadId, att)
// after
const ext = ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)
if (!ext?.ingestAttachments) throw new Error('RAG extension must be registered before uploading documents')
await uploads.ingestFileAttachment(threadId, att) Defensive patterns
Strategy: validation
Validate before calling
const ext = ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)
if (!ext?.ingestAttachments) throw new Error('RAG extension with ingestAttachments must be registered before uploading documents') Type guard
const hasRagIngest = (): boolean => !!ExtensionManager.getInstance().get<RAGExtension>(ExtensionTypeEnum.RAG)?.ingestAttachments
Try / catch
try {
await uploads.ingestFileAttachment(threadId, att)
} catch (e) {
if (e instanceof Error && e.message === 'RAG extension not available') {
showExtensionSetupPrompt('Install/enable the RAG extension to upload documents')
return
}
throw e
} Prevention
- Register the RAG extension during app bootstrap before enabling upload features
- Gate document-upload UI on a capability check (ext?.ingestAttachments)
- Pin @janhq/core versions between app and extensions and review its changelog for RAGExtension interface changes
When it happens
Trigger: Calling ingestFileAttachment when no extension is registered under ExtensionTypeEnum.RAG, or the registered extension lacks an ingestAttachments implementation (ext is null or ext.ingestAttachments is undefined).
Common situations: The RAG extension was never installed/registered at app startup; extension registration runs after the upload call; a core version upgrade renamed or removed ingestAttachments from the RAGExtension interface.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- llamacpp extension not available
- RAG extension does not support project-level ingestion
- Conversational extension not available yet
- Extension does not support backend installation
- Extension does not support backend updates
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/783a4a1d55645287.
Report an issue: GitHub.
Appendix: source
Thrown at web-app/src/services/uploads/default.ts:18
import type { UploadsService, UploadResult } from './types'
import type { Attachment } from '@/types/attachment'
import { ulid } from 'ulidx'
import { ExtensionManager } from '@/lib/extension'
import { ExtensionTypeEnum, type RAGExtension, type IngestAttachmentsResult } from '@janhq/core'
export class DefaultUploadsService implements UploadsService {
async ingestImage(_threadId: string, attachment: Attachment): Promise<UploadResult> {
if (attachment.type !== 'image') throw new Error('ingestImage: attachment is not image')
// Placeholder upload flow; swap for real API call when backend is ready
await new Promise((r) => setTimeout(r, 100))
return { id: ulid() }
}
async ingestFileAttachment(threadId: string, attachment: Attachment): Promise<UploadResult> {
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')View on GitHub (pinned to 7205d770c1)