{"record":{"id":"2778a7260d684342","repo":"hashicorp/terraform","slug":"invalid-tfvars-content-s","errorCode":null,"errorMessage":"invalid tfvars content: %s","messagePattern":"invalid tfvars content: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/builtin/providers/terraform/functions.go","lineNumber":125,"sourceCode":"\n\t// If we get here then we know that:\n\t// - there's exactly one element in args\n\t// - it's a string\n\t// - it is known and non-null\n\t// So therefore the following is guaranteed to succeed.\n\tsrc := []byte(args[0].AsString())\n\n\t// As usual when we wrap HCL stuff up in functions, we end up needing to\n\t// stuff HCL diagnostics into plain string error messages. This produces\n\t// a non-ideal result but is still better than hiding the HCL-provided\n\t// diagnosis altogether.\n\tf, hclDiags := hclsyntax.ParseConfig(src, \"<decode_tfvars argument>\", hcl.InitialPos)\n\tif hclDiags.HasErrors() {\n\t\treturn cty.NilVal, fmt.Errorf(\"invalid tfvars syntax: %s\", hclDiags.Error())\n\t}\n\tattrs, hclDiags := f.Body.JustAttributes()\n\tif hclDiags.HasErrors() {\n\t\treturn cty.NilVal, fmt.Errorf(\"invalid tfvars content: %s\", hclDiags.Error())\n\t}\n\tretAttrs := make(map[string]cty.Value, len(attrs))\n\tfor name, attr := range attrs {\n\t\t// Evaluating the expression with no EvalContext achieves the same\n\t\t// interpretation as Terraform CLI makes of .tfvars files, rejecting\n\t\t// any function calls or references to symbols.\n\t\tv, hclDiags := attr.Expr.Value(nil)\n\t\tif hclDiags.HasErrors() {\n\t\t\treturn cty.NilVal, fmt.Errorf(\"invalid expression for variable %q: %s\", name, hclDiags.Error())\n\t\t}\n\t\tretAttrs[name] = v\n\t}\n\n\treturn cty.ObjectVal(retAttrs), nil\n}\n\nfunc encodeExprFunc(args []cty.Value) (cty.Value, error) {\n\t// These error checks should not be hit in practice because the language","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/builtin/providers/terraform/functions.go#L107-L143","documentation":"Thrown by the built-in `decode_tfvars` function (functions.go:125) when the input string parses as valid HCL but its body cannot be read as tfvars attributes via `f.Body.JustAttributes()`. This happens when the body contains nested blocks or other non-attribute constructs that are legal HCL but illegal in a `.tfvars` file. The error wraps the underlying HCL diagnostic verbatim.","triggerScenarios":"Calling `decode_tfvars(\"...\")` in an HCL expression where the argument string contains a nested block such as `foo { bar = 1 }`, a duplicate attribute, or a construct HCL accepts as a block. The earlier `hclsyntax.ParseConfig` succeeds (so [121] is not triggered) but `JustAttributes()` rejects the block-shaped body.","commonSituations":"Feeding a full `.tf` configuration file into `decode_tfvars`; passing JSON/YAML text instead of tfvars syntax; reusing a variable file that mixed attribute and block syntax; copy-pasting an object literal with `{ }` braces rather than `key = value` lines.","solutions":["Rewrite the input as flat top-level `key = value` attributes only — no nested blocks.","If the source is JSON, use `jsondecode(...)` instead of `decode_tfvars(...)`.","If you need nested structures, encode them as HCL values on the right-hand side, e.g. `servers = [\"a\", \"b\"]` rather than a block.","Run `terraform fmt` on the candidate string in a scratch `.tfvars` file to surface the offending construct quickly."],"exampleFix":"// before\ndecode_tfvars(<<-EOT\n  env {\n    name = \"prod\"\n  }\nEOT\n)\n\n// after\ndecode_tfvars(<<-EOT\n  env_name = \"prod\"\nEOT\n)","handlingStrategy":"validation","validationCode":"// Pre-validate a tfvars string before handing it to decode_tfvars.\nfunc isValidTfvarsBody(src string) error {\n    f, diags := hclsyntax.ParseConfig([]byte(src), \"<check>\", hcl.InitialPos)\n    if diags.HasErrors() {\n        return fmt.Errorf(\"syntax: %s\", diags.Error())\n    }\n    if _, diags := f.Body.JustAttributes(); diags.HasErrors() {\n        return fmt.Errorf(\"not flat tfvars attributes: %s\", diags.Error())\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat decode_tfvars input as literal-only `key = value` lines; never include nested blocks.","If you generate tfvars programmatically, emit attribute assignments only.","Keep a canonical .tfvars file under test and round-trip it through encode_tfvars/decode_tfvars in CI."],"tags":["terraform","hcl","decode-tfvars","built-in-function","user-input"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}