{"record":{"id":"8c792da4049f10c2","repo":"larksuite/cli","slug":"must-be-finite","errorCode":null,"errorMessage":"must be finite","messagePattern":"must be finite","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/common/typed_compile_args.go","lineNumber":554,"sourceCode":"\t\t\tresult.Encoding = typedCLIEncoding(value)\n\t\tdefault:\n\t\t\treturn result, fmt.Errorf(\"unknown cli token %q\", key)\n\t\t}\n\t}\n\treturn result, nil\n}\n\nfunc parseFiniteFloat(value string) (float64, error) {\n\treturn parseFiniteFloatBits(value, 64)\n}\n\nfunc parseFiniteFloatBits(value string, bits int) (float64, error) {\n\tparsed, err := strconv.ParseFloat(value, bits)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif math.IsNaN(parsed) || math.IsInf(parsed, 0) {\n\t\treturn 0, fmt.Errorf(\"must be finite\")\n\t}\n\treturn parsed, nil\n}\n\nfunc parseNonnegativeInt(value string) (int, error) {\n\tparsed, err := strconv.ParseUint(value, 10, 31)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"must be a nonnegative integer: %w\", err)\n\t}\n\treturn int(parsed), nil\n}\n\nfunc indirectType(t reflect.Type) reflect.Type {\n\tfor t.Kind() == reflect.Pointer {\n\t\tt = t.Elem()\n\t}\n\treturn t\n}","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/common/typed_compile_args.go#L536-L572","documentation":"parseFiniteFloatBits (used by parseFiniteFloat and shapeForType) rejects NaN and +/-Inf because JSON cannot represent them and default/bound values must marshal cleanly. When strconv.ParseFloat succeeds but returns a non-finite value, this error replaces it with a clear 'must be finite' message. It is a compile-time/tag-value validation error.","triggerScenarios":"Passing a default, minimum, or maximum value of NaN, +Inf, or -Inf (e.g. from a tag like `default:\"NaN\"` or computed input) to a float-typed schema value.","commonSituations":"Using sentinel constants like math.Inf(1) or math.NaN() as defaults; parsing user config that contains 'Infinity' or 'NaN' strings.","solutions":["Replace the NaN/Inf value with a finite number","If a max value means 'unbounded', omit maximum/minItems-style bounds instead of using Inf","Clamp or sanitize the value before assigning it as a default"],"exampleFix":"// before\nMax: func() float64 { return math.Inf(1) }()\n// after\n// omit the maximum bound entirely, or use a concrete finite limit\nMax: 1e12","handlingStrategy":"validation","validationCode":"func isFinite(f float64) bool { return !math.IsNaN(f) && !math.IsInf(f, 0) }\nif !isFinite(defaultVal) { return fmt.Errorf(\"default must be finite\") }","typeGuard":"func isFiniteFloat(v any) bool {\n\tf, ok := v.(float64)\n\treturn ok && !math.IsNaN(f) && !math.IsInf(f, 0)\n}","tryCatchPattern":null,"preventionTips":["Never use math.NaN or math.Inf as defaults or bounds","Omit bounds rather than encoding 'unlimited' as Inf","Validate any config-supplied numbers with isFinite before use"],"tags":["go","float","json","validation"],"backgroundTag":"non-finite-number-value","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}