{"record":{"id":"a1a9bf1310ee7122","repo":"pathwaycom/pathway","slug":"pw-schema-has-column-names-that-differ-only-in-cas","errorCode":null,"errorMessage":"pw.Schema has column names that differ only in case ({case_collisions}). DuckDB treats identifiers case-insensitively, so CREATE TABLE would reject them as duplicates. Rename these columns in the Pathway table so every column name is unique case-insensitively.","messagePattern":"pw\\.Schema has column names that differ only in case \\((.+?)\\)\\. DuckDB treats identifiers case-insensitively, so CREATE TABLE would reject them as duplicates\\. Rename these columns in the Pathway table so every column name is unique case-insensitively\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/duckdb/__init__.py","lineNumber":297,"sourceCode":"            'detach_between_batches=True cannot be used with database=\":memory:\": '\n            \"an in-memory DuckDB database is dropped when its last connection \"\n            \"closes, so all data would be lost after every batch. Use an on-disk \"\n            \"database file instead.\"\n        )\n\n    value_fields = _format_output_value_fields(table)\n\n    # DuckDB matches identifiers case-insensitively, so two schema columns whose\n    # names differ only in case would make CREATE TABLE fail with a raw\n    # \"Column with name ... already exists\" catalog error. Surface it here.\n    case_groups: dict[str, list[str]] = {}\n    for field in value_fields:\n        case_groups.setdefault(field.name.lower(), []).append(field.name)\n    case_collisions = [\n        sorted(names) for names in case_groups.values() if len(names) > 1\n    ]\n    if case_collisions:\n        raise ValueError(\n            f\"pw.Schema has column names that differ only in case \"\n            f\"({case_collisions}). DuckDB treats identifiers case-insensitively, \"\n            \"so CREATE TABLE would reject them as duplicates. Rename these columns \"\n            \"in the Pathway table so 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 to the\n        # destination table. If the user's own schema already has a column with\n        # one of those names, the generated CREATE TABLE would declare that column\n        # twice. Catch it here with a clear message instead of an opaque driver\n        # error at start-up.\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        )","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/duckdb/__init__.py#L279-L315","documentation":"Raised by pw.io.duckdb.write when the Pathway table's schema contains two or more column names that differ only in letter case (e.g. 'Name' and 'name'). DuckDB matches identifiers case-insensitively, so the generated CREATE TABLE would fail with a raw 'Column with name ... already exists' catalog error; the connector surfaces it up front with a clear message.","triggerScenarios":"pw.io.duckdb.write(t, table_name=\"t\") where t's schema declares columns like userId and UserID, or where a rename/with_columns produced case-variant names.","commonSituations":"Ingesting CSV/JSON sources with inconsistent header casing; joining or unioning tables from different producers that each normalized casing differently; applying .rename() or selecting prefixed columns that collide case-insensitively.","solutions":["Rename the colliding columns in the Pathway table before writing: t.select(**{c.lower(): t[c] for c in t.column_names()}) or targeted t.rename(...).","Fix the source schema / headers so every column name is unique case-insensitively.","Drop one of the duplicate-cased columns with t.without() if it is redundant."],"exampleFix":"# before\n# schema has columns: Name, name\npw.io.duckdb.write(t, table_name=\"t\", database=\"out.duckdb\")\n\n# after\nt = t.rename(**{\"Name\": \"full_name\"})\npw.io.duckdb.write(t, table_name=\"t\", database=\"out.duckdb\")","handlingStrategy":"validation","validationCode":"names = [c for c in table.column_names()]\nlowered = {}\nfor n in names:\n    lowered.setdefault(n.lower(), []).append(n)\ncollisions = {k: v for k, v in lowered.items() if len(v) > 1}\nassert not collisions, f\"case-insensitive duplicate columns: {collisions}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Normalize column casing (e.g. all lower_snake_case) right after ingest from CSV/JSON.","Add a unit test asserting len(set(n.lower() for n in table.column_names())) == len(table.column_names()) before writes."],"tags":["duckdb","schema","case-sensitivity","connector"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}