{"record":{"id":"901a891d1bebf846","repo":"hashicorp/terraform","slug":"must-not-be-a-whole-number","errorCode":null,"errorMessage":"must not be a whole number","messagePattern":"must not be a whole number","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/backendbase/helper.go","lineNumber":111,"sourceCode":"\t\treturn fallback\n\t}\n\treturn ret\n}\n\n// IntValue converts a cty value into a Go int64, or returns an error if that's\n// not possible.\nfunc IntValue(v cty.Value) (int64, error) {\n\tv, err := convert.Convert(v, cty.Number)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif v.IsNull() {\n\t\treturn 0, fmt.Errorf(\"must not be null\")\n\t}\n\tbf := v.AsBigFloat()\n\tret, acc := bf.Int64()\n\tif acc != big.Exact {\n\t\treturn 0, fmt.Errorf(\"must not be a whole number\")\n\t}\n\treturn ret, nil\n}\n\n// BoolValue converts a cty value Go bool, or returns an error if that's not\n// possible.\nfunc BoolValue(v cty.Value) (bool, error) {\n\tv, err := convert.Convert(v, cty.Bool)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tif v.IsNull() {\n\t\treturn false, fmt.Errorf(\"must not be null\")\n\t}\n\treturn v.True(), nil\n}\n\n// MustBoolValue converts a cty value Go bool, or panics if that's not possible.","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/backendbase/helper.go#L93-L129","documentation":"Returned by backendbase.IntValue when the cty.Number value is non-null but its big.Float does not convert to int64 exactly (big.Accuracy != big.Exact). In other words the user supplied a fractional number where the backend schema requires a whole number.","triggerScenarios":"Returned at internal/backend/backendbase/helper.go:111 when bf.Int64() returns acc != big.Exact. Used by the http backend for retry_max / retry_wait_min / retry_wait_max (and any backend calling IntValue for an int field).","commonSituations":"Setting `retry_wait_max = 2.5` (seconds) or any decimal where the backend expects an integer count/seconds. Misreading a duration field that actually wants whole seconds. Copy-pasting a float default from docs.","solutions":["Change the value to a whole number: `retry_wait_max = 3`.","If sub-second precision is needed, check whether the backend supports a finer unit; otherwise round up/down to the nearest integer.","Review the backend's documented schema to confirm the attribute is an integer.","Validate user-supplied config with a 'must be integer' check before init."],"exampleFix":"// before (fractional -> 'must not be a whole number')\nbackend \"http\" {\n  address       = \"https://state.example.com\"\n  retry_wait_max = 2.5\n}\n// after\nbackend \"http\" {\n  address       = \"https://state.example.com\"\n  retry_wait_max = 3\n}","handlingStrategy":"validation","validationCode":"// Reject fractional numbers before IntValue.\nif v.Type() == cty.Number {\n    bf := v.AsBigFloat()\n    if _, acc := bf.Int64(); acc != big.Exact {\n        return errors.New(\"value must be a whole number\")\n    }\n}","typeGuard":"func isNonIntegerError(err error) bool {\n    return err != nil && err.Error() == \"must not be a whole number\"\n}","tryCatchPattern":"n, err := backendbase.IntValue(v)\nif err != nil {\n    // surface with the attribute name for clarity\n    return fmt.Errorf(\"%s: %w\", attrName, err)\n}","preventionTips":["Use whole numbers for integer backend fields.","Round/ceil programmatically before config if needed.","Validate config int-ness before init."],"tags":["backend","config","validation","integer","http-backend"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}