{"record":{"id":"2d70828c89270108","repo":"n8n-io/n8n","slug":"metadata-key-content-key-is-reserved-for-the","errorCode":null,"errorMessage":"Metadata key \"${CONTENT_KEY}\" is reserved for the document content and cannot be set.","messagePattern":"Metadata key \"(.+?)\" is reserved for the document content and cannot be set\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/vector-stores/pinecone.ts","lineNumber":151,"sourceCode":"\n\tfor (const item of items) {\n\t\tconst itemBytes = Buffer.byteLength(JSON.stringify(item));\n\t\tif (batch.length > 0 && (batch.length >= maxCount || batchBytes + itemBytes > maxBytes)) {\n\t\t\tbatches.push(batch);\n\t\t\tbatch = [];\n\t\t\tbatchBytes = 0;\n\t\t}\n\t\tbatch.push(item);\n\t\tbatchBytes += itemBytes;\n\t}\n\tif (batch.length > 0) batches.push(batch);\n\n\treturn batches;\n}\n\nfunction toPineconeMetadata(content: string, metadata: JSONObject): RecordMetadata {\n\tif (CONTENT_KEY in metadata) {\n\t\tthrow new Error(\n\t\t\t`Metadata key \"${CONTENT_KEY}\" is reserved for the document content and cannot be set.`,\n\t\t);\n\t}\n\tconst result: RecordMetadata = { [CONTENT_KEY]: content };\n\tfor (const [key, value] of Object.entries(metadata)) {\n\t\tassertValidMetadataValue(key, value);\n\t\tresult[key] = value;\n\t}\n\treturn result;\n}\n\n/** Pinecone metadata values are flat: string, number, boolean, or an array of strings — no nested objects or null. */\nfunction assertValidMetadataValue(\n\tkey: string,\n\tvalue: JSONValue | undefined,\n): asserts value is string | number | boolean | string[] {\n\tif (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n\t\treturn;","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/vector-stores/pinecone.ts#L133-L169","documentation":"Thrown by toPineconeMetadata during upsert when the caller's metadata object already contains the reserved key `_content` (CONTENT_KEY). Pinecone has no dedicated content column, so document content is stored under `_content` alongside the caller's metadata; letting a caller set it would overwrite or shadow the real content. The check runs before any Pinecone request is sent.","triggerScenarios":"Upserting a VectorDocument whose metadata is `{ _content: '...', topic: 'x' }`; importing records from another system that already used `_content` as a metadata field; an ETL pipeline that prefixes all fields with underscore.","commonSituations":"Migrating from a schema where `_content` was a normal field; auto-prefixing metadata keys; field-name collision from a third-party data feed; re-upserting records previously enriched with their own `_content` metadata.","solutions":["Rename the `_content` metadata key in your records to something else (e.g. `content_summary`, `body`).","If the value really is the document content, set it as `doc.content` (the VectorDocument.content field) instead of in metadata.","Strip `_content` from metadata during your ETL/import step before calling addDocuments."],"exampleFix":"// before\nawait store.addDocuments([{\n  content: 'Real body text',\n  metadata: { _content: 'collision', topic: 'billing' },\n}]);\n\n// after\nawait store.addDocuments([{\n  content: 'Real body text',\n  metadata: { topic: 'billing' },\n}]);","handlingStrategy":"validation","validationCode":"const RESERVED = '_content';\n\nfunction sanitizeMetadata(metadata: Record<string, unknown>): Record<string, unknown> {\n  if (RESERVED in metadata) {\n    throw new Error(`Metadata key \"${RESERVED}\" is reserved; rename or drop it`);\n  }\n  return metadata;\n}\n\nawait store.addDocuments(docs.map((d) => ({ ...d, metadata: sanitizeMetadata(d.metadata ?? {}) })));","typeGuard":"function isSafeMetadataKey(key: string): boolean {\n  return key !== '_content';\n}\n","tryCatchPattern":"// Strip the reserved key before upsert if it might be present:\nconst clean = (m: Record<string, unknown>) => {\n  const { _content, ...rest } = m as Record<string, unknown>;\n  return rest;\n};\nawait store.addDocuments(docs.map((d) => ({ ...d, metadata: clean(d.metadata ?? {}) })));","preventionTips":["Treat `_content` as off-limits in your metadata schema; document the reserved key for anyone writing ingest code.","Put real document text in VectorDocument.content, not in metadata.","Add an ETL step that drops/renames `_content` from imported records before addDocuments."],"tags":["pinecone","metadata","vector-store","reserved-key"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}