{"record":{"id":"46379b6431e06324","repo":"FlowiseAI/Flowise","slug":"sourceidkey-should-be-null-a-string-or-a-function","errorCode":null,"errorMessage":"sourceIdKey should be null, a string or a function, got ${typeof sourceIdKey}","messagePattern":"sourceIdKey should be null, a string or a function, got (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/src/indexing.ts","lineNumber":220,"sourceCode":"        }\n\n        if (!seen.has(hashedDoc.hash_)) {\n            seen.add(hashedDoc.hash_)\n            deduplicated.push(hashedDoc)\n        }\n    }\n    return deduplicated\n}\n\nexport function _getSourceIdAssigner(sourceIdKey: StringOrDocFunc | null): (doc: DocumentInterface) => string | null {\n    if (sourceIdKey === null) {\n        return (_doc: DocumentInterface) => null\n    } else if (typeof sourceIdKey === 'string') {\n        return (doc: DocumentInterface) => doc.metadata[sourceIdKey]\n    } else if (typeof sourceIdKey === 'function') {\n        return sourceIdKey\n    } else {\n        throw new Error(`sourceIdKey should be null, a string or a function, got ${typeof sourceIdKey}`)\n    }\n}\n\nexport const _isBaseDocumentLoader = (arg: any): arg is BaseDocumentLoader => {\n    if ('load' in arg && typeof arg.load === 'function' && 'loadAndSplit' in arg && typeof arg.loadAndSplit === 'function') {\n        return true\n    }\n    return false\n}\n\ninterface IndexArgs {\n    docsSource: BaseDocumentLoader | DocumentInterface[]\n    recordManager: ExtendedRecordManagerInterface\n    vectorStore: VectorStore\n    options?: IndexOptions\n}\n\n/**","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/src/indexing.ts#L202-L238","documentation":"Thrown by _getSourceIdAssigner() when the sourceIdKey option is neither null, a string, nor a function. The function builds a closure that extracts a source ID from each document for incremental cleanup; an invalid type (number, boolean, object, array) cannot be used as a key or extractor and is rejected at line 220.","triggerScenarios":"Passing options.sourceIdKey as a number (e.g. 0), a boolean, an object, or an array to index(). The type check chain at lines 213-219 exhausts null/string/function and falls through to the throw.","commonSituations":"Loading options from JSON config where the sourceIdKey field is numeric or null-ish in a way that bypasses the truthiness guard at line 261 but still isn't a string/function. Programmatic misconfiguration. A typo passing the wrong variable (e.g. an index instead of a key name).","solutions":["Set options.sourceIdKey to a metadata key string (e.g. 'source') or a (doc) => string function.","Validate the config value's type before calling index() and coerce or reject it.","If you do not need incremental cleanup, set cleanup to undefined or 'full' and omit sourceIdKey.","Add a runtime assertion at the config-loading boundary so bad types are caught early with a clear message."],"exampleFix":"// before\nawait index({ docsSource, recordManager, vectorStore, options: { cleanup: 'incremental', sourceIdKey: 0 } })\n\n// after\nawait index({ docsSource, recordManager, vectorStore, options: { cleanup: 'incremental', sourceIdKey: 'source' } })","handlingStrategy":"type-guard","validationCode":"function assertSourceIdKey(v: unknown): asserts v is string | ((doc: any) => string) | null {\n  if (v !== null && typeof v !== 'string' && typeof v !== 'function') {\n    throw new TypeError(`sourceIdKey must be string|function|null, got ${typeof v}`)\n  }\n}\n\nassertSourceIdKey(options.sourceIdKey)\nawait index({ docsSource, recordManager, vectorStore, options })","typeGuard":"function isValidSourceIdKey(v: unknown): v is string | ((doc: any) => string) | null {\n  return v === null || typeof v === 'string' || typeof v === 'function'\n}","tryCatchPattern":null,"preventionTips":["Type the config field explicitly as string | ((doc) => string) | null.","Validate config values loaded from JSON before passing to index().","Add a unit test that feeds each accepted type plus a rejected type."],"tags":["indexing","validation","typescript","langchain","type-error"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}