{"record":{"id":"3571ab402bf46ec3","repo":"dotnet/machinelearning","slug":"invalid-call-to-getgetter","errorCode":null,"errorMessage":"Invalid call to 'GetGetter'","messagePattern":"Invalid call to 'GetGetter'","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.ML.DataView/DataViewSchema.cs","lineNumber":229,"sourceCode":"            private void CheckGetter<TValue>(Delegate getter)\n            {\n                var typedGetter = getter as ValueGetter<TValue>;\n                if (typedGetter == null)\n                    throw new ArgumentNullException(nameof(getter), $\"Getter of type '{typeof(TValue)}' expected, but {getter.GetType()} found\");\n            }\n\n            /// <summary>\n            /// Get a getter delegate for one value of the annotations row.\n            /// </summary>\n            public ValueGetter<TValue> GetGetter<TValue>(DataViewSchema.Column column)\n            {\n                if (column.Index >= _getters.Length)\n                    throw new ArgumentException(nameof(column));\n                var typedGetter = _getters[column.Index] as ValueGetter<TValue>;\n                if (typedGetter == null)\n                {\n                    Debug.Assert(_getters[column.Index] != null);\n                    throw new InvalidOperationException($\"Invalid call to '{nameof(GetGetter)}'\");\n                }\n                return typedGetter;\n            }\n\n            /// <summary>\n            /// Get the value of an annotation, by annotation kind (aka column name).\n            /// </summary>\n            public void GetValue<TValue>(string kind, ref TValue value)\n            {\n                var column = Schema.GetColumnOrNull(kind);\n                if (column == null)\n                    throw new InvalidOperationException($\"Invalid call to '{nameof(GetValue)}'\");\n                GetGetter<TValue>(column.Value)(ref value);\n            }\n\n            public override string ToString() => string.Join(\", \", Schema.Select(x => x.Name));\n\n            internal Delegate GetGetterInternal(int index)","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/dotnet/machinelearning/blob/7b76e69cf964daeca3f1377af6bc5543284d56c6/src/Microsoft.ML.DataView/DataViewSchema.cs#L211-L247","documentation":"DataViewSchema.GetGetter<TValue> returns the typed ValueGetter<TValue> for a column, but the stored getter for that column index is either not a ValueGetter<TValue> of the requested type or is null. This means the caller asked for the column's value with a TValue that does not match the column's declared type. The library throws because returning null would silently break downstream row cursors.","triggerScenarios":"Calling schema.GetGetter<int>(col) on a column whose actual value type is float/ReadOnlyMemory<char>/VBuffer<etc>; casting a weakly-typed Delegate getter to the wrong ValueGetter<TValue>; reusing a getter obtained from a different schema after a transform changed column types.","commonSituations":"Hand-rolling a row cursor over a DataView and hard-coding a TValue; using GetGetter inside annotation/annotation-kind lookups with a mismatched generic; code written against one pipeline version breaking after upstream transforms change a column's type.","solutions":["Check column.Type.RawType (or GetAnnotationType) and use exactly that type as TValue in GetGetter<TValue>","Use the weakly-typed GetGetterInternal/Delegate path and convert with Utils.MarshalActionInvoke (or MarshalInvoke) instead of a fixed generic","Inspect the column's DataViewType and slot structure before writing the cursor loop; if the type is dynamic, dispatch per-type"],"exampleFix":"// before\nvar getter = schema.GetGetter<int>(schema[\"Features\"]);\n// after\nif (schema[\"Features\"].Type.RawType == typeof(VBuffer<float>))\n    var getter = schema.GetGetter<VBuffer<float>>(schema[\"Features\"]);","handlingStrategy":"type-guard","validationCode":"var col = schema[\"Features\"];\nif (col.Type.RawType != typeof(VBuffer<float>))\n    throw new InvalidOperationException($\"Expected VBuffer<float>, got {col.Type.RawType}\");\nvar getter = schema.GetGetter<VBuffer<float>>(col);","typeGuard":"bool IsTyped<TValue>(DataViewSchema.Column c) => c.Type.RawType == typeof(TValue);","tryCatchPattern":"try { getter = schema.GetGetter<TValue>(col); }\ncatch (InvalidOperationException)\n{\n    var actual = col.Type.RawType;\n    getter = MarshalGetter<TValue>(col, actual); // dispatch on actual type\n}","preventionTips":["Always check column.Type.RawType before choosing TValue for GetGetter","Never hard-code generic types for dynamically-typed columns","Use GetGetterInternal + MarshalActionInvoke for weakly-typed cursor code","Re-verify types after pipeline changes; transforms can alter column types"],"tags":["dotnet","mlnet","type-mismatch","dataview"],"backgroundTag":"type-mismatch","analyzedSha":"7b76e69cf964daeca3f1377af6bc5543284d56c6","analyzedAt":"2026-09-11T12:35:38.930Z","contentChangedAt":"2026-09-11T12:35:38.930Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}