{"record":{"id":"34f1f47a45e0f2f7","repo":"FlowiseAI/Flowise","slug":"failed-to-hash-metadata-e-please-use-a-dict-t","errorCode":null,"errorMessage":"Failed to hash metadata: ${e}. Please use a dict that can be serialized using json.","messagePattern":"Failed to hash metadata: (.+?)\\. Please use a dict that can be serialized using json\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/src/indexing.ts","lineNumber":95,"sourceCode":"    calculateHashes(): void {\n        const forbiddenKeys = ['hash_', 'content_hash', 'metadata_hash']\n\n        for (const key of forbiddenKeys) {\n            if (key in this.metadata) {\n                throw new Error(\n                    `Metadata cannot contain key ${key} as it is reserved for internal use. Restricted keys: [${forbiddenKeys.join(', ')}]`\n                )\n            }\n        }\n\n        const contentHash = this._hashStringToUUID(this.pageContent)\n\n        try {\n            const metadataHash = this._hashNestedDictToUUID(this.metadata)\n            this.contentHash = contentHash\n            this.metadataHash = metadataHash\n        } catch (e) {\n            throw new Error(`Failed to hash metadata: ${e}. Please use a dict that can be serialized using json.`)\n        }\n\n        this.hash_ = this._hashStringToUUID(this.contentHash + this.metadataHash)\n\n        if (!this.uid) {\n            this.uid = this.hash_\n        }\n    }\n\n    toDocument(): DocumentInterface {\n        return new Document({\n            pageContent: this.pageContent,\n            metadata: this.metadata\n        })\n    }\n\n    static fromDocument(document: DocumentInterface, uid?: string): _HashedDocument {\n        const doc = new this({","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/src/indexing.ts#L77-L113","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst docs = [{ pageContent: 'x', metadata: { self: null } }]\ndocs[0].metadata.self = docs[0].metadata // circular\nawait index({ docsSource: docs, recordManager, vectorStore })\n\n// after\nfunction toSafeMeta(obj, seen = new WeakSet()) {\n  if (obj && typeof obj === 'object') {\n    if (seen.has(obj)) return null\n    seen.add(obj)\n    const out = Array.isArray(obj) ? [] : {}\n    for (const [k, v] of Object.entries(obj)) out[k] = toSafeMeta(v, seen)\n    return out\n  }\n  return typeof obj === 'function' ? null : obj\n}\nconst docs = rawDocs.map(d => ({ ...d, metadata: toSafeMeta(d.metadata) }))","handlingStrategy":"validation","validationCode":"// Ensure metadata is JSON-safe before indexing\nfunction toSafeMetadata(obj: unknown, seen = new WeakSet()): unknown {\n  if (obj === null || typeof obj !== 'object') {\n    return typeof obj === 'function' || typeof obj === 'symbol' ? null : obj\n  }\n  if (seen.has(obj as object)) return null\n  seen.add(obj as object)\n  if (typeof (obj as any).toJSON === 'function') return (obj as any).toJSON()\n  if (typeof (obj as any).toISOString === 'function') return (obj as any).toISOString()\n  const out: Record<string, unknown> = {}\n  for (const [k, v] of Object.entries(obj as object)) {\n    out[k] = toSafeMetadata(v, seen)\n  }\n  return out\n}\n\nconst safeDocs = docs.map((d) => ({ ...d, metadata: toSafeMetadata(d.metadata) as Record<string, unknown> }))","typeGuard":"function isJsonSafe(value: unknown): boolean {\n  try { JSON.stringify(value); return true } catch { return false }\n}\n\nfunction hasJsonSafeMetadata(doc: { metadata: unknown }): boolean {\n  return isJsonSafe(doc.metadata)\n}","tryCatchPattern":"try {\n  await index({ docsSource, recordManager, vectorStore, options })\n} catch (e) {\n  if (String(e).includes('Failed to hash metadata')) {\n    const sanitized = docs.map((d) => ({ ...d, metadata: toSafeMetadata(d.metadata) }))\n    await index({ docsSource: sanitized, recordManager, vectorStore, options })\n  } else throw e\n}","preventionTips":["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."],"tags":["indexing","metadata","serialization","json","langchain"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}