{"record":{"id":"b34a13d41815db5c","repo":"hashicorp/packer","slug":"unhandled-buildvar-type-t","errorCode":null,"errorMessage":"unhandled buildvar type: %T","messagePattern":"unhandled buildvar type: %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hcl2template/utils.go","lineNumber":186,"sourceCode":"\t\t\tvals[i] = cty.NumberIntVal(ev)\n\t\t}\n\t\tif len(vals) == 0 {\n\t\t\tbuildValue = cty.ListValEmpty(cty.Number)\n\t\t} else {\n\t\t\tbuildValue = cty.ListVal(vals)\n\t\t}\n\tcase []uint64:\n\t\tvals := make([]cty.Value, len(v))\n\t\tfor i, ev := range v {\n\t\t\tvals[i] = cty.NumberUIntVal(ev)\n\t\t}\n\t\tif len(vals) == 0 {\n\t\t\tbuildValue = cty.ListValEmpty(cty.Number)\n\t\t} else {\n\t\t\tbuildValue = cty.ListVal(vals)\n\t\t}\n\tdefault:\n\t\treturn cty.Value{}, fmt.Errorf(\"unhandled buildvar type: %T\", v)\n\t}\n\treturn buildValue, nil\n}\n\n// GetVarsByType walks through a hcl body, and gathers all the Traversals that\n// have a root type matching one of the specified top-level labels.\n//\n// This will only work on finite, expanded, HCL bodies.\nfunc GetVarsByType(block *hcl.Block, topLevelLabels ...string) []hcl.Traversal {\n\tvar travs []hcl.Traversal\n\n\tswitch body := block.Body.(type) {\n\tcase *hclsyntax.Body:\n\t\ttravs = getVarsByTypeForHCLSyntaxBody(body)\n\tdefault:\n\t\tattrs, _ := body.JustAttributes()\n\t\tfor _, attr := range attrs {\n\t\t\ttravs = append(travs, attr.Expr.Variables()...)","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/hcl2template/utils.go#L168-L204","documentation":"ConvertPluginConfigValueToHCLValue converts a plugin-provided build variable (a plain Go interface{}) into a cty.Value for HCL2 interpolation. Packer throws this error when the value's Go type is not one of the supported kinds (bool, string, uint8, float64, int64, uint64, []string, []uint8, []int64, []uint64), so it cannot be represented as an HCL value.","triggerScenarios":"HCL2Prepare (on HCL2Provisioner or HCL2PostProcessor) iterates buildVars and calls this converter; a build variable of an unhandled type — e.g. int (plain, not int64), map[string]string, []interface{}, nil, or a struct — hits the default branch.","commonSituations":"A builder or plugin passes build variables with types outside the whitelist (e.g. Go int or a map) via the build's generated variables; a caller constructs buildVars map[string]interface{} manually with an int or nested value instead of the supported primitives/slices.","solutions":["Coerce the build variable to a supported type before passing it: convert Go int to int64, maps/structs to string (e.g. JSON-encode), and []interface{} to []string","Fix the plugin/builder code that produces the variable so it emits one of the supported types","If it's your code calling ConvertPluginConfigValueToHCLValue, pre-validate types with a type switch and convert unsupported ones yourself","Check the Packer/SDK version: newer SDKs may type values differently; align the producer and consumer versions"],"exampleFix":"// before\nbuildVars[\"port\"] = 8080 // Go int -> unhandled\n// after\nbuildVars[\"port\"] = int64(8080) // or strconv.Itoa: buildVars[\"port\"] = \"8080\"","handlingStrategy":"type-guard","validationCode":"func isSupportedBuildVarType(v interface{}) bool {\n\tswitch v.(type) {\n\tcase bool, string, uint8, float64, int64, uint64, []string, []uint8, []int64, []uint64:\n\t\treturn true\n\t}\n\treturn false\n}","typeGuard":"func coerceBuildVar(v interface{}) interface{} {\n\tswitch t := v.(type) {\n\tcase int:\n\t\treturn int64(t)\n\tcase int32:\n\t\treturn int64(t)\n\tcase uint:\n\t\treturn uint64(t)\n\tcase map[string]interface{}:\n\t\tb, _ := json.Marshal(t)\n\t\treturn string(b)\n\tdefault:\n\t\treturn v\n\t}\n}","tryCatchPattern":null,"preventionTips":["Only populate buildVars with the documented supported types; normalize ints to int64 and maps to strings","When writing plugins, follow the SDK conventions for generated variable types","Add a unit test that round-trips every build variable through ConvertPluginConfigValueToHCLValue","Check plugin/SDK version compatibility when upgrading"],"tags":["hcl2","type-conversion","buildvars","cty","packer"],"backgroundTag":"unhandled-value-type","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}