FlowiseAI/Flowise · error · Error
Failed to hash metadata: ${e}. Please use a dict that can be
Error message
Failed to hash metadata: ${e}. Please use a dict that can be serialized using json. What it means
Thrown by _HashedDocument.calculateHashes() when the internal _hashNestedDictToUUID() call fails during metadata hashing. _hashNestedDictToUUID uses JSON.stringify with a custom replacer (Object.keys(data).sort()) to serialize metadata before hashing; if the metadata contains values that JSON cannot represent (functions, symbols, circular references, BigInt), serialization throws and the catch at line 94 wraps it.
Source
Thrown at packages/components/src/indexing.ts:95
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) {
this.uid = this.hash_
}
}
toDocument(): DocumentInterface {
return new Document({
pageContent: this.pageContent,
metadata: this.metadata
})
}
static fromDocument(document: DocumentInterface, uid?: string): _HashedDocument {
const doc = new this({View on GitHub (pinned to abe4a8601a)
Solutions
- Sanitize metadata to plain JSON-safe values (strings, numbers, booleans, arrays, plain objects, null) before indexing.
- Break circular references or replace them with IDs.
- Convert class instances to plain objects (e.g. date.toISOString(), bigint.toString()).
- Run JSON.stringify(doc.metadata) in a pre-check to catch the offending field early.
Example fix
// before
const docs = [{ pageContent: 'x', metadata: { self: null } }]
docs[0].metadata.self = docs[0].metadata // circular
await index({ docsSource: docs, recordManager, vectorStore })
// after
function toSafeMeta(obj, seen = new WeakSet()) {
if (obj && typeof obj === 'object') {
if (seen.has(obj)) return null
seen.add(obj)
const out = Array.isArray(obj) ? [] : {}
for (const [k, v] of Object.entries(obj)) out[k] = toSafeMeta(v, seen)
return out
}
return typeof obj === 'function' ? null : obj
}
const docs = rawDocs.map(d => ({ ...d, metadata: toSafeMeta(d.metadata) })) Defensive patterns
Strategy: validation
Validate before calling
// Ensure metadata is JSON-safe before indexing
function toSafeMetadata(obj: unknown, seen = new WeakSet()): unknown {
if (obj === null || typeof obj !== 'object') {
return typeof obj === 'function' || typeof obj === 'symbol' ? null : obj
}
if (seen.has(obj as object)) return null
seen.add(obj as object)
if (typeof (obj as any).toJSON === 'function') return (obj as any).toJSON()
if (typeof (obj as any).toISOString === 'function') return (obj as any).toISOString()
const out: Record<string, unknown> = {}
for (const [k, v] of Object.entries(obj as object)) {
out[k] = toSafeMetadata(v, seen)
}
return out
}
const safeDocs = docs.map((d) => ({ ...d, metadata: toSafeMetadata(d.metadata) as Record<string, unknown> })) Type guard
function isJsonSafe(value: unknown): boolean {
try { JSON.stringify(value); return true } catch { return false }
}
function hasJsonSafeMetadata(doc: { metadata: unknown }): boolean {
return isJsonSafe(doc.metadata)
} Try / catch
try {
await index({ docsSource, recordManager, vectorStore, options })
} catch (e) {
if (String(e).includes('Failed to hash metadata')) {
const sanitized = docs.map((d) => ({ ...d, metadata: toSafeMetadata(d.metadata) }))
await index({ docsSource: sanitized, recordManager, vectorStore, options })
} else throw e
} Prevention
- Restrict metadata to JSON-native primitives and plain objects.
- Convert Dates to ISO strings and BigInts to strings at the loader stage.
- Run JSON.stringify on metadata during ingestion and reject/log failures.
When it happens
Trigger: A Document whose metadata contains a non-JSON-serializable value: a circular reference, a function, a Symbol-keyed or Symbol-valued property, a BigInt, or a class instance without toJSON. JSON.stringify throws and the catch re-throws with this message.
Common situations: Metadata that includes class instances (e.g. a Date object is fine, but a custom class is not), circular references from parent/child links, functions attached as metadata by mistake, or BigInt IDs from a database driver. Documents built from ORM entities that carry back-references.
Related errors
- Metadata cannot contain key ${key} as it is reserved for int
- 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/34f1f47a45e0f2f7.
Report an issue: GitHub.