{"record":{"id":"8f6dd142c4c54a54","repo":"pathwaycom/pathway","slug":"column-s-collisions-collide-with-the-time-and-8f6dd1","errorCode":null,"errorMessage":"Column(s) {collisions} collide with the 'time' and 'diff' metadata columns appended in stream_of_changes mode. Rename these columns in the Pathway table, or use output_table_type=\"snapshot\".","messagePattern":"Column\\(s\\) (.+?) collide with the 'time' and 'diff' metadata columns appended in stream_of_changes mode\\. Rename these columns in the Pathway table, or use output_table_type=\"snapshot\"\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/mssql/__init__.py","lineNumber":426,"sourceCode":"            \"every column name is unique case-insensitively.\"\n        )\n\n    if not is_snapshot_mode:\n        # Stream-of-changes mode appends `[time]` / `[diff]` metadata columns\n        # to the destination table.  If the user's own schema already has a\n        # column with one of those names, the generated CREATE TABLE would\n        # declare it twice and SQL Server would reject it with an opaque\n        # \"duplicate column name\" error at startup.  Comparison is\n        # case-insensitive — SQL Server's default collation treats `Time` and\n        # `time` as the same identifier.\n        reserved_metadata_columns = {\"time\", \"diff\"}\n        collisions = sorted(\n            field.name\n            for field in value_fields\n            if field.name.lower() in reserved_metadata_columns\n        )\n        if collisions:\n            raise ValueError(\n                f\"Column(s) {collisions} collide with the 'time' and 'diff' \"\n                \"metadata columns appended in stream_of_changes mode. Rename \"\n                \"these columns in the Pathway table, or use \"\n                'output_table_type=\"snapshot\".'\n            )\n\n    data_storage = api.DataStorage(\n        storage_type=\"mssql\",\n        connection_string=connection_string,\n        max_batch_size=max_batch_size,\n        table_name=table_name,\n        schema_name=schema_name,\n        table_writer_init_mode=init_mode_from_str(init_mode),\n        snapshot_maintenance_on_output=is_snapshot_mode,\n    )\n\n    key_field_names = None\n    if primary_key is not None:","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/mssql/__init__.py#L408-L444","documentation":"In stream_of_changes mode, pw.io.mssql.write appends 'time' and 'diff' metadata columns to the destination table. If the Pathway table already has a column whose name matches 'time' or 'diff' (case-insensitively, per SQL Server collation), the generated CREATE TABLE would declare it twice and SQL Server would reject it with an opaque duplicate-column error. Pathway raises this ValueError at write() time instead.","triggerScenarios":"Calling pw.io.mssql.write(table, name) with default output_table_type and a schema containing a column named time, Time, diff, or DIFF.","commonSituations":"Event/log tables that naturally carry a timestamp column named 'time'; CDC-style pipelines where 'diff' is a natural column name; porting schemas from systems where these names are unrestricted.","solutions":["Rename the colliding column(s) before the sink, e.g. table.select(**{k: v for ...}) mapping time -> event_time or diff -> change_diff.","Or switch the sink to output_table_type=\"snapshot\", which does not append the metadata columns."],"exampleFix":"# before\ntable = table.select(table.id, table.time, table.value)\npw.io.mssql.write(table, \"events\")\n\n# after\ntable = table.select(table.id, event_time=table.time, table.value)\npw.io.mssql.write(table, \"events\")","handlingStrategy":"validation","validationCode":"RESERVED = {\"time\", \"diff\"}\n\nbad = [n for n in table.schema.column_names() if n.lower() in RESERVED]\nif bad and output_table_type != \"snapshot\":\n    table = table.rename(**{n: f\"pw_{n}\" for n in bad})","typeGuard":"def is_safe_for_stream_sink(column_names: list[str]) -> bool:\n    return all(n.lower() not in (\"time\", \"diff\") for n in column_names)","tryCatchPattern":"try:\n    pw.io.mssql.write(table, \"events\")\nexcept ValueError as e:\n    if \"metadata columns\" in str(e):\n        pw.io.mssql.write(table, \"events\", output_table_type=\"snapshot\")\n    else:\n        raise","preventionTips":["Avoid naming sink-bound columns bare 'time' or 'diff' (any casing).","Prefer descriptive names like event_time / change_diff from the start.","If the names come from upstream data, rename in the last select before the sink."],"tags":["mssql","reserved-columns","stream-mode","sink","pathway"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}