{"record":{"id":"0019e347a9c1a24b","repo":"hashicorp/terraform","slug":"either-a-string-or-an-integer-is-required","errorCode":null,"errorMessage":"either a string or an integer is required","messagePattern":"either a string or an integer is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/addrs/instance_key.go","lineNumber":48,"sourceCode":"}\n\n// ParseInstanceKey returns the instance key corresponding to the given value,\n// which must be known and non-null.\n//\n// If an unknown or null value is provided then this function will panic. This\n// function is intended to deal with the values that would naturally be found\n// in a hcl.TraverseIndex, which (when parsed from source, at least) can never\n// contain unknown or null values.\nfunc ParseInstanceKey(key cty.Value) (InstanceKey, error) {\n\tswitch key.Type() {\n\tcase cty.String:\n\t\treturn StringKey(key.AsString()), nil\n\tcase cty.Number:\n\t\tvar idx int\n\t\terr := gocty.FromCtyValue(key, &idx)\n\t\treturn IntKey(idx), err\n\tdefault:\n\t\treturn NoKey, fmt.Errorf(\"either a string or an integer is required\")\n\t}\n}\n\n// NoKey represents the absense of an InstanceKey, for the single instance\n// of a configuration object that does not use \"count\" or \"for_each\" at all.\nvar NoKey InstanceKey\n\n// WildcardKey represents the \"unknown\" value of an InstanceKey. This is used\n// within the deferral logic to express absolute module and resource addresses\n// that are not known at the time of planning.\nvar WildcardKey InstanceKey = &wildcardKey{}\n\n// wildcardKey is a special kind of InstanceKey that represents the \"unknown\"\n// value of an InstanceKey. This is used within the deferral logic to express\n// absolute module and resource addresses that are not known at the time of\n// planning.\ntype wildcardKey struct{}\n","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/addrs/instance_key.go#L30-L66","documentation":"Returned by addrs.ParseInstanceKey when the supplied cty.Value's type is neither cty.String nor cty.Number — i.e. it cannot be used as a count index (int) or for_each key (string). ParseInstanceKey is explicitly documented to panic on null/unknown and to error on any other type via this message.","triggerScenarios":"Calling ParseInstanceKey with a cty.Value of an unexpected type (bool, list, object, dynamic pseudo-type). Naturally reached from hcl.TraverseIndex parsing, which only ever yields string/number, so seeing this error implies programmatic misuse.","commonSituations":"Custom code building instance keys from arbitrary cty values without first narrowing the type; a schema change feeding a non-scalar into a traversal index; downstream code re-parsing an already-keyed address with the wrong value kind.","solutions":["Ensure the value passed to ParseInstanceKey is known, non-null, and of type cty.String or cty.Number.","Add a type guard (key.Type() == cty.String || key.Type() == cty.Number) before calling.","If you hold an hcl.TraverseIndex, extract its key only after confirming the traversal source; do not construct cty values of other types.","For unknown/null inputs, decide on a sentinel (NoKey / WildcardKey) before invoking ParseInstanceKey, since it panics on those."],"exampleFix":"// before\nk, err := addrs.ParseInstanceKey(maybeVal)\n\n// after\nif maybeVal.Type() != cty.String && maybeVal.Type() != cty.Number {\n    return addrs.NoKey, fmt.Errorf(\"instance key must be string or number, got %s\", maybeVal.Type().FriendlyName())\n}\nk, err := addrs.ParseInstanceKey(maybeVal)","handlingStrategy":"type-guard","validationCode":"// Narrow the type before parsing\nif key.IsNull() || !key.IsKnown() {\n    return addrs.NoKey, errors.New(\"instance key must be known and non-null\")\n}","typeGuard":"func isParsableInstanceKey(v cty.Value) bool {\n    t := v.Type()\n    return (t == cty.String || t == cty.Number) && !v.IsNull() && v.IsKnown()\n}","tryCatchPattern":"if !isParsableInstanceKey(v) {\n    return addrs.NoKey, fmt.Errorf(\"instance key must be a known, non-null string or number, got %s\", v.Type().FriendlyName())\n}\nk, err := addrs.ParseInstanceKey(v)","preventionTips":["Always check v.Type() is cty.String or cty.Number before calling ParseInstanceKey.","Never pass null/unknown values — ParseInstanceKey panics on them.","If iterating hcl.TraverseIndex, the key is already constrained to string/number."],"tags":["addrs","instance-key","type-error","terraform"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}