{"record":{"id":"5a15accb16230621","repo":"hashicorp/terraform","slug":"must-not-be-null","errorCode":null,"errorMessage":"must not be null","messagePattern":"must not be null","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/backendbase/helper.go","lineNumber":106,"sourceCode":"// Unless the fallback value is null itself, this function guarantees to never\n// return null.\nfunc GetAttrEnvDefaultFallback(v cty.Value, attrName string, defEnv string, fallback cty.Value) cty.Value {\n\tret := GetAttrEnvDefault(v, attrName, defEnv)\n\tif ret.IsNull() {\n\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\")","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/backendbase/helper.go#L88-L124","documentation":"Returned by backendbase.IntValue when the cty.Value, after successful conversion to cty.Number, is null. The function expects a non-null number it can convert to int64; a null value fails at helper.go:105-107. (Note: a value that fails convert.Convert to Number returns a different, conversion-specific error earlier.)","triggerScenarios":"Calling IntValue on a backend config attribute that was declared but not set (null) — e.g. an optional numeric backend attribute the user omitted.","commonSituations":"Backend config attribute is optional and the user did not provide it; upstream code did not apply GetPathDefault/GetPathEnvDefaultFallback to substitute a non-null default before calling IntValue; the value came from a variable resolving to null.","solutions":["Substitute a non-null default with GetPathDefault / GetAttrEnvDefaultFallback before calling IntValue.","Check v.IsNull() yourself and skip or use a default instead of calling IntValue.","Make the backend schema attribute Required so Terraform rejects null at config-load time.","If null is a legitimate 'unset', branch on it rather than forcing conversion."],"exampleFix":"// before\nn, err := backendbase.IntValue(cfg.GetAttr(\"port\"))\n\n// after\nportVal := backendbase.GetAttrEnvDefaultFallback(cfg, \"port\", \"TF_BACKEND_PORT\", cty.NumberIntVal(8080))\nn, err := backendbase.IntValue(portVal)","handlingStrategy":"validation","validationCode":"// Apply a default before calling IntValue\nportVal := backendbase.GetAttrEnvDefaultFallback(cfg, \"port\", \"TF_PORT\", cty.NumberIntVal(8080))\nif portVal.IsNull() {\n    return errors.New(\"port is required\")\n}","typeGuard":"func isNonNullNumber(v cty.Value) bool {\n    return !v.IsNull() && v.Type() == cty.Number\n}","tryCatchPattern":"if cfg.GetAttr(\"port\").IsNull() {\n    return errors.New(\"port must be set\")\n}\nn, err := backendbase.IntValue(cfg.GetAttr(\"port\"))","preventionTips":["Apply defaults with GetAttrDefault/GetAttrEnvDefaultFallback before IntValue.","Make numeric attributes Required when they have no sensible default.","Branch on IsNull() instead of forcing conversion of optional values."],"tags":["backend","cty","null-value","validation","terraform"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}