FlowiseAI/Flowise · error · Error
Metadata cannot contain key ${key} as it is reserved for int
Error message
Metadata cannot contain key ${key} as it is reserved for internal use. Restricted keys: [${forbiddenKeys.join(', ')}] What it means
Thrown by _HashedDocument.calculateHashes() when document metadata contains one of the reserved internal keys: 'hash_', 'content_hash', or 'metadata_hash'. These keys are written by the indexer itself to track document identity; allowing user metadata to set them would collide with the indexing bookkeeping and corrupt deduplication. The check runs before hashes are computed.
Source
Thrown at packages/components/src/indexing.ts:82
metadataHash?: string
pageContent: string
metadata: Metadata
constructor(fields: HashedDocumentArgs) {
this.uid = fields.uid
this.pageContent = fields.pageContent
this.metadata = fields.metadata
}
calculateHashes(): void {
const forbiddenKeys = ['hash_', 'content_hash', 'metadata_hash']
for (const key of forbiddenKeys) {
if (key in this.metadata) {
throw new Error(
`Metadata cannot contain key ${key} as it is reserved for internal use. Restricted keys: [${forbiddenKeys.join(', ')}]`
)
}
}
const contentHash = this._hashStringToUUID(this.pageContent)
try {
const metadataHash = this._hashNestedDictToUUID(this.metadata)
this.contentHash = contentHash
this.metadataHash = metadataHash
} catch (e) {
throw new Error(`Failed to hash metadata: ${e}. Please use a dict that can be serialized using json.`)
}
this.hash_ = this._hashStringToUUID(this.contentHash + this.metadataHash)
if (!this.uid) {View on GitHub (pinned to abe4a8601a)
Solutions
- Rename the conflicting key in your metadata before indexing (e.g. 'content_hash' → 'source_content_hash').
- Strip reserved keys in a pre-indexing transform: delete doc.metadata.hash_ etc.
- Namespace your metadata under a prefix to avoid future collisions (e.g. 'user_hash_').
- Validate metadata keys against the reserved list at the document-ingestion boundary so the error never reaches the indexer.
Example fix
// before
const docs = [{ pageContent: 'hello', metadata: { content_hash: 'abc', source: 'x' } }]
await index({ docsSource: docs, recordManager, vectorStore, options: { cleanup: 'incremental', sourceIdKey: 'source' } })
// after
const RESERVED = ['hash_', 'content_hash', 'metadata_hash']
const docs = rawDocs.map(d => ({
...d,
metadata: Object.fromEntries(Object.entries(d.metadata).filter(([k]) => !RESERVED.includes(k)))
})) Defensive patterns
Strategy: validation
Validate before calling
const RESERVED_META_KEYS = ['hash_', 'content_hash', 'metadata_hash']
function stripReservedMetadata<T extends { metadata: Record<string, unknown> }>(doc: T): T {
const cleaned = Object.fromEntries(
Object.entries(doc.metadata).filter(([k]) => !RESERVED_META_KEYS.includes(k))
)
return { ...doc, metadata: cleaned }
}
const safeDocs = docs.map(stripReservedMetadata) Type guard
function hasReservedMeta(meta: Record<string, unknown>): boolean {
return ['hash_', 'content_hash', 'metadata_hash'].some((k) => k in meta)
} Try / catch
try {
await index({ docsSource, recordManager, vectorStore, options })
} catch (e) {
if (String(e).includes('reserved for internal use')) {
const cleaned = docs.map(stripReservedMetadata)
await index({ docsSource: cleaned, recordManager, vectorStore, options })
} else throw e
} Prevention
- Validate metadata keys at the document-ingestion boundary.
- Namespace custom metadata under a stable prefix to avoid collisions.
- Document the reserved-keys list for downstream metadata authors.
When it happens
Trigger: Passing a Document to index() whose metadata object has a top-level key named 'hash_', 'content_hash', or 'metadata_hash'. The forbidden loop at lines 80-86 scans the metadata keys and throws on the first collision. This happens during _HashedDocument.fromDocument() → calculateHashes() for every document in every batch.
Common situations: User-uploaded documents whose metadata schema happens to use these key names. Migrating from another indexing system that used 'content_hash'. Documents enriched by a pipeline that computes its own hashes and stores them in metadata. A search/indexing feature that lets end-users attach arbitrary metadata.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Failed to hash metadata: ${e}. Please use a dict that can be
- sourceIdKey should be null, a string or a function, got ${ty
- sourceIdKey is required when cleanup mode is incremental. Pl
- sourceIdKey must be provided when cleanup is incremental
- Source id cannot be null
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/df0cf7a4e6839ece.
Report an issue: GitHub.