{"record":{"id":"ad4b4aa241280e1b","repo":"dotnet/aspnetcore","slug":"range-validator-requires-at-least-one-of-min-or","errorCode":null,"errorMessage":"Range validator requires at least one of \"min\" or \"max\" parameters.","messagePattern":"Range validator requires at least one of \"min\" or \"max\" parameters\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Validation/Validators/Range.ts","lineNumber":12,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nimport { ValidationContext, ValidationResult, Validator, pass, fail } from '../ValidationTypes';\n\n// Validates that a numeric value falls within min/max bounds (inclusive).\n// Non-numeric values fail. Uses Number() for parsing.\n// Throws if neither bound is defined (rule has no effect).\nexport const rangeValidator: Validator = (context: ValidationContext): ValidationResult => {\n  const { value, params } = context;\n  if (params.min === undefined && params.max === undefined) {\n    throw new Error('Range validator requires at least one of \"min\" or \"max\" parameters.');\n  }\n\n  if (!value) {\n    return pass();\n  }\n\n  const num = Number(value);\n  if (isNaN(num)) {\n    return fail();\n  }\n\n  if (params.min !== undefined) {\n    if (num < Number(params.min)) {\n      return fail();\n    }\n  }\n\n  if (params.max !== undefined) {","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Web.JS/src/Validation/Validators/Range.ts#L1-L30","documentation":"Thrown by the Range validator (Range.ts:12) when both params.min and params.max are undefined. Range enforces inclusive numeric bounds; with neither bound the rule is a no-op, so the validator throws to flag a rule that would silently validate everything. At least one bound must be supplied.","triggerScenarios":"Invoking rangeValidator with a params object containing neither 'min' nor 'max'. Typically emitted from [Range(min,max)]; if both arguments are missing or the data-val-range-min/max metadata is absent, the JS validator throws.","commonSituations":"Model uses [Range] with no arguments (compile error in C# but possible via dynamic metadata), or a custom edit form drops both data-val-range-min and data-val-range-max. Manual validator registration that omits bounds. Serialization edge cases where 0 bounds are sent as missing.","solutions":["Use [Range(1, 100)] (or [Range(typeof(decimal), \"0\", \"10\")]) on the property and confirm the rendered input has data-val-range-min and/or data-val-range-max.","When wiring manually, pass params: { min: '1', max: '100' } (at least one required).","Distinguish a real bound of 0 from a missing bound — ensure 0 is serialized as the string \"0\", not omitted.","Verify data-val-range-* attributes survive any custom rendering/tag-helper pipeline."],"exampleFix":"// before\n<input name=\"Age\" data-val-range />\n\n// after\n<input name=\"Age\" data-val-range data-val-range-min=\"18\" data-val-range-max=\"120\" />","handlingStrategy":"validation","validationCode":"function hasRangeBound(params: Record<string, unknown>): boolean {\n  return params && (params.min !== undefined || params.max !== undefined);\n}","typeGuard":"function isRangeConfigured(p: any): p is { min?: string; max?: string } {\n  return p && (p.min !== undefined || p.max !== undefined);\n}","tryCatchPattern":null,"preventionTips":["Always provide at least one bound on [Range].","Serialize numeric bounds (including 0) as strings, not omitted.","Verify data-val-range-min/max render on the input.","Test that '0' is not collapsed to missing by serializers."],"tags":["validation","blazor","forms","range","configuration"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}