{"record":{"id":"aa6bb02406bc9aeb","repo":"dotnet/machinelearning","slug":"value-cannot-be-null-parameter-getter-getter","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'getter')\nGetter of type '{typeof(TValue)}' expected, but {getter.GetType()} found","messagePattern":"Value cannot be null\\. \\(Parameter 'getter'\\)\nGetter of type '(.+?)' expected, but (.+?) found","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.ML.DataView/DataViewSchema.cs","lineNumber":215,"sourceCode":"\n                Debug.Assert(schema.Count == getters.Length);\n                // Check all getters.\n                for (int i = 0; i < schema.Count; i++)\n                {\n                    var getter = getters[i];\n                    if (getter == null)\n                        throw new ArgumentNullException(nameof(getter), $\"Delegate at index '{i}' of {nameof(getters)} was null.\");\n                    Utils.MarshalActionInvoke(CheckGetter<int>, schema[i].Type.RawType, getter);\n                }\n                Schema = schema;\n                _getters = getters;\n            }\n\n            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","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/dotnet/machinelearning/blob/7b76e69cf964daeca3f1377af6bc5543284d56c6/src/Microsoft.ML.DataView/DataViewSchema.cs#L197-L233","documentation":"CheckGetter<TValue> verifies each annotation getter is a ValueGetter<TValue> matching the declared annotation column's RawType; if the delegate exists but has the wrong type, it throws ArgumentNullException naming 'getter' with a message showing the expected TValue and the actual delegate type. This is a type-conformance check even though it throws ArgumentNullException.","triggerScenarios":"Passing a Delegate to Annotations whose runtime type is not ValueGetter<TValue> for the corresponding schema slot's RawType — e.g. a ValueGetter<float> supplied where the annotation type is double, or a plain lambda typed as Action/Func instead of ValueGetter.","commonSituations":"Mismatched annotation type declarations vs. getter implementations; refactoring that changed TValue of the getter but not the annotation schema; boxing conversions (int getter for uint annotation).","solutions":["Align each getter to ValueGetter<TValue> where TValue equals the annotation column's Type.RawType.","Cast/construct the delegate explicitly as (ValueGetter<TValue>)((ref TValue value) => ...) so the compiler enforces the type.","Fix the annotation schema declaration to match the getter type actually provided.","Add a unit test constructing the Annotations to catch type drift early."],"exampleFix":"// before\nDelegate g = (ValueGetter<float>)(ref float v) => v = 1f; // annotation slot is RawType double\nnew Annotations(schema, new Delegate[] { g });\n// after\nDelegate g = (ValueGetter<double>)(ref double v) => v = 1.0; // matches RawType\nnew Annotations(schema, new Delegate[] { g });","handlingStrategy":"type-guard","validationCode":"bool ok = getter is ValueGetter<double> && schema[0].Type.RawType == typeof(double);","typeGuard":"bool IsTypedGetter<TValue>(Delegate g) => g is ValueGetter<TValue>;","tryCatchPattern":null,"preventionTips":["Declare getters as explicit ValueGetter<TValue> so the compiler catches mismatches","Keep annotation schema types and getter types in sync; test Annotations construction"],"tags":["dotnet","type-mismatch","delegate","annotations"],"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"}