{"record":{"id":"667e98fbbb543d02","repo":"pathwaycom/pathway","slug":"column-name-id-is-reserved-mongodb-uses-id","errorCode":null,"errorMessage":"Column name '_id' is reserved: MongoDB uses '_id' as the primary key for every document, so pw.io.mongodb.write cannot accept a column with this name. Rename the column before writing.","messagePattern":"Column name '_id' is reserved: MongoDB uses '_id' as the primary key for every document, so pw\\.io\\.mongodb\\.write cannot accept a column with this name\\. Rename the column before writing\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/mongodb/__init__.py","lineNumber":649,"sourceCode":"                \"numCandidates\": 100,\n                \"limit\": 5,\n            }},\n            {\"$project\": {\"_id\": 0, \"doc_id\": 1,\n                          \"score\": {\"$meta\": \"vectorSearchScore\"}}},\n        ])\n\n    **Note on parallelism.** When the program is run with multiple workers\n    (``pathway spawn -n N``), the write is distributed across them, and write\n    throughput grows with the worker count up to the capacity of the target\n    MongoDB/Atlas deployment. Each document is written by a single worker, so the\n    result is the same as with one worker. The exception is ``sort_by``: requesting\n    a global order within a minibatch makes the connector write from a single\n    worker, so a sorted output does not benefit from additional workers.\n    \"\"\"\n    is_snapshot_mode = output_table_type == SNAPSHOT_OUTPUT_TABLE_TYPE\n    column_names = set(table.schema.column_names())\n    if \"_id\" in column_names:\n        raise ValueError(\n            \"Column name '_id' is reserved: MongoDB uses '_id' as the primary key \"\n            \"for every document, so pw.io.mongodb.write cannot accept a column with \"\n            \"this name. Rename the column before writing.\"\n        )\n    if not is_snapshot_mode:\n        reserved = {\"diff\", \"time\"} & column_names\n        if reserved:\n            raise ValueError(\n                f\"Column name(s) {sorted(reserved)!r} collide with the reserved \"\n                f\"fields written by pw.io.mongodb.write in 'stream_of_changes' mode. \"\n                f\"Rename the column(s) or use output_table_type='snapshot'.\"\n            )\n    data_storage = api.DataStorage(\n        storage_type=\"mongodb\",\n        connection_string=connection_string,\n        database=database,\n        table_name=collection,\n        max_batch_size=max_batch_size,","sourceCodeStart":631,"sourceCodeEnd":667,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/mongodb/__init__.py#L631-L667","documentation":"MongoDB reserves _id as the mandatory primary key of every document and the connector generates it itself, so pw.io.mongodb.write refuses an input table that has a column literally named '_id'. Passing one through would collide with the connector-managed identifier and corrupt upserts, so it raises ValueError asking you to rename.","triggerScenarios":"pw.io.mongodb.write(table, uri, db, coll) where table's schema contains a column named '_id' — typically a table that was previously read from MongoDB or built from BSON documents verbatim.","commonSituations":"Round-tripping: read from Mongo, transform, write back with the original _id still present; converting raw dicts (from pymongo) to a Pathway table without stripping _id.","solutions":["Rename or drop the column before writing: table = table.rename(_id='mongo_id') or table.without(_id) if Mongo may regenerate ids","If you must preserve original ids, let the connector key on a renamed copy: table.rename(_id='source_id')","Strip _id when ingesting raw documents upstream (del doc['_id']) when identity does not matter"],"exampleFix":"# before\npw.io.mongodb.write(t, uri, db, coll)  # t has column '_id'\n\n# after\nt = t.rename(_id='source_doc_id')\npw.io.mongodb.write(t, uri, db, coll)","handlingStrategy":"validation","validationCode":"names = set(table.schema.column_names())\nif \"_id\" in names:\n    raise ValueError(\"Rename the '_id' column before pw.io.mongodb.write\")\n# or fix: table = table.rename(_id='source_doc_id')","typeGuard":"def has_reserved_mongo_names(table: pw.Table) -> bool:\n    return \"_id\" in table.schema.column_names()","tryCatchPattern":"try:\n    pw.io.mongodb.write(table, uri, db, coll)\nexcept ValueError as e:\n    if \"'_id' is reserved\" in str(e):\n        pw.io.mongodb.write(table.rename(_id='source_doc_id'), uri, db, coll)\n    else:\n        raise","preventionTips":["Rename _id when reading Mongo documents into Pathway tables meant for write-back","Strip _id at ingestion when document identity can be regenerated","Include reserved-name checks in your connector wrapper helpers"],"tags":["mongodb","pathway","reserved-name","schema","validation"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}