n8n-io/n8n · error
Metadata key "${CONTENT_KEY}" is reserved for the document c
Error message
Metadata key "${CONTENT_KEY}" is reserved for the document content and cannot be set. What it means
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.
Source
Thrown at packages/@n8n/agents/src/vector-stores/pinecone.ts:151
for (const item of items) {
const itemBytes = Buffer.byteLength(JSON.stringify(item));
if (batch.length > 0 && (batch.length >= maxCount || batchBytes + itemBytes > maxBytes)) {
batches.push(batch);
batch = [];
batchBytes = 0;
}
batch.push(item);
batchBytes += itemBytes;
}
if (batch.length > 0) batches.push(batch);
return batches;
}
function toPineconeMetadata(content: string, metadata: JSONObject): RecordMetadata {
if (CONTENT_KEY in metadata) {
throw new Error(
`Metadata key "${CONTENT_KEY}" is reserved for the document content and cannot be set.`,
);
}
const result: RecordMetadata = { [CONTENT_KEY]: content };
for (const [key, value] of Object.entries(metadata)) {
assertValidMetadataValue(key, value);
result[key] = value;
}
return result;
}
/** Pinecone metadata values are flat: string, number, boolean, or an array of strings — no nested objects or null. */
function assertValidMetadataValue(
key: string,
value: JSONValue | undefined,
): asserts value is string | number | boolean | string[] {
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
return;View on GitHub (pinned to 5ac6606e81)
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.
Example fix
// before
await store.addDocuments([{
content: 'Real body text',
metadata: { _content: 'collision', topic: 'billing' },
}]);
// after
await store.addDocuments([{
content: 'Real body text',
metadata: { topic: 'billing' },
}]); Defensive patterns
Strategy: validation
Validate before calling
const RESERVED = '_content';
function sanitizeMetadata(metadata: Record<string, unknown>): Record<string, unknown> {
if (RESERVED in metadata) {
throw new Error(`Metadata key "${RESERVED}" is reserved; rename or drop it`);
}
return metadata;
}
await store.addDocuments(docs.map((d) => ({ ...d, metadata: sanitizeMetadata(d.metadata ?? {}) }))); Type guard
function isSafeMetadataKey(key: string): boolean {
return key !== '_content';
}
Try / catch
// Strip the reserved key before upsert if it might be present:
const clean = (m: Record<string, unknown>) => {
const { _content, ...rest } = m as Record<string, unknown>;
return rest;
};
await store.addDocuments(docs.map((d) => ({ ...d, metadata: clean(d.metadata ?? {}) }))); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Metadata value for key "${key}" is unsupported: Pinecone onl
- Filter operator "${operator}" on key "${key}" requires a non
- Index ${credentials.pineconeIndex} not found
- Index ${index} not found
- Unexpected score type: ${typeof score}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/2d70828c89270108.
Report an issue: GitHub.