{"record":{"id":"6daa69400fc3d6c2","repo":"tursodatabase/turso","slug":"column-name-name-is-ambiguous-between-column1","errorCode":null,"errorMessage":"Column name {name} is ambiguous between {column1} and {column2}.","messagePattern":"Column name (.+?) is ambiguous between (.+?) and (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data.Sqlite/SqliteDataReader.cs","lineNumber":380,"sourceCode":"    public override int GetOrdinal(string name)\n    {\n        EnsureOpen();\n        ArgumentNullException.ThrowIfNull(name);\n        _ = GetStatement();\n        for (var i = 0; i < FieldCount; i++)\n        {\n            if (string.Equals(GetName(i), name, StringComparison.Ordinal))\n                return i;\n        }\n\n        string? match = null;\n        var matchOrdinal = -1;\n        for (var i = 0; i < FieldCount; i++)\n        {\n            if (string.Equals(GetName(i), name, StringComparison.OrdinalIgnoreCase))\n            {\n                if (match is not null)\n                    throw new InvalidOperationException(Properties.Resources.AmbiguousColumnName(name, match, GetName(i)));\n\n                match = GetName(i);\n                matchOrdinal = i;\n            }\n        }\n\n        if (match is not null)\n            return matchOrdinal;\n\n        throw new ArgumentOutOfRangeException(nameof(name), name, $\"Column {name} was not found.\");\n    }\n\n    public override DataTable GetSchemaTable()\n    {\n        EnsureOpen();\n        var statement = GetStatement();\n        var schema = new DataTable(\"SchemaTable\");\n        schema.Columns.Add(SchemaTableColumn.ColumnName, typeof(string));","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/dotnet/src/Turso.Data.Sqlite/SqliteDataReader.cs#L362-L398","documentation":"InvalidOperationException thrown by GetOrdinal when the exact case-sensitive lookup finds nothing but the case-insensitive fallback matches two or more columns whose names differ only by casing (e.g. 'ID' and 'id' from a JOIN). The reader first tries an ordinal match, then collects case-insensitive matches; more than one is ambiguous because the caller's intent cannot be determined. The message names both conflicting columns.","triggerScenarios":"SELECT a.Id, b.id FROM t a JOIN u b ... then GetOrdinal(\"id\"); queries over quoted mixed-case identifiers created with \"MyColumn\" vs MYCOLUMN; SQLite's ASCII case-insensitive identifier rules letting two such columns coexist.","commonSituations":"Joining tables with inconsistent identifier casing conventions; databases originally created on case-sensitive filesystems or ported from other engines; ORM-generated joins exposing both spellings in one projection.","solutions":["Use the exact casing of the intended column — the ordinal (case-sensitive) pass runs first and returns immediately.","Alias the duplicated columns in the query: SELECT a.Id AS a_id, b.id AS b_id, then GetOrdinal(\"a_id\").","As a last resort, resolve by ordinal (SELECT column order) or via reader.GetName(i) scans."],"exampleFix":"// before\nSELECT a.Id, b.id FROM orders a JOIN users b ON ...;\nvar i = reader.GetOrdinal(\"id\"); // ambiguous\n\n// after\nSELECT a.Id AS order_id, b.id AS user_id FROM orders a JOIN users b ON ...;\nvar i = reader.GetOrdinal(\"user_id\");","handlingStrategy":"validation","validationCode":"int ResolveExact(SqliteDataReader r, string name)\n{\n    var hits = Enumerable.Range(0, r.FieldCount)\n        .Where(i => string.Equals(r.GetName(i), name, StringComparison.OrdinalIgnoreCase)).ToList();\n    if (hits.Count > 1) throw new InvalidOperationException($\"'{name}' matches {hits.Count} columns; use exact case or alias.\");\n    return hits.Count == 1 ? hits[0] : throw new ArgumentOutOfRangeException(nameof(name), name);\n}","typeGuard":null,"tryCatchPattern":"try { var i = reader.GetOrdinal(name); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"ambiguous\"))\n{ /* switch to exact-case name or a query alias */ }","preventionTips":["Alias every column in multi-table JOINs so names are unique.","Standardize identifier casing in your schema (one convention everywhere)."],"tags":["csharp","dotnet","sqlite","data-reader","column-mapping"],"backgroundTag":"ambiguous-column-name","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}