hashicorp/terraform · error
either a string or an integer is required
Error message
either a string or an integer is required
What it means
Returned by ParseInstanceKey when the cty.Value passed in is neither a String nor a Number — the only two index types Terraform permits for count/for_each instances. The function explicitly panics on null/unknown values (documented), so reaching the default branch means a value of some other concrete type (bool, list, object, etc.) was used as an index.
Source
Thrown at internal/addrs/instance_key.go:48
}
// ParseInstanceKey returns the instance key corresponding to the given value,
// which must be known and non-null.
//
// If an unknown or null value is provided then this function will panic. This
// function is intended to deal with the values that would naturally be found
// in a hcl.TraverseIndex, which (when parsed from source, at least) can never
// contain unknown or null values.
func ParseInstanceKey(key cty.Value) (InstanceKey, error) {
switch key.Type() {
case cty.String:
return StringKey(key.AsString()), nil
case cty.Number:
var idx int
err := gocty.FromCtyValue(key, &idx)
return IntKey(idx), err
default:
return NoKey, fmt.Errorf("either a string or an integer is required")
}
}
// NoKey represents the absense of an InstanceKey, for the single instance
// of a configuration object that does not use "count" or "for_each" at all.
var NoKey InstanceKey
// WildcardKey represents the "unknown" value of an InstanceKey. This is used
// within the deferral logic to express absolute module and resource addresses
// that are not known at the time of planning.
var WildcardKey InstanceKey = &wildcardKey{}
// wildcardKey is a special kind of InstanceKey that represents the "unknown"
// value of an InstanceKey. This is used within the deferral logic to express
// absolute module and resource addresses that are not known at the time of
// planning.
type wildcardKey struct{}
View on GitHub (pinned to c9def3e214)
Solutions
- Change the index expression to evaluate to a string or integer: `resource["name"]` or `resource[0]`.
- If iterating, ensure for_each maps to strings and count to integers; never use a bool/complex value as the key.
- When parsing addresses programmatically, validate the index token type before calling ParseInstanceKey.
- Audit the generated/templated HCL if the address comes from codegen.
Example fix
// before (bool index -> error)
resource "aws_instance" "web" {
count = var.enabled ? 1 : 0
}
// referencing as aws_instance.web[true] fails
// after
output "first" { value = aws_instance.web[0].id } Defensive patterns
Strategy: type-guard
Validate before calling
// Only feed String/Number values to ParseInstanceKey.
func isParsableKey(v cty.Value) bool {
return v.Type() == cty.String || v.Type() == cty.Number
}
if !isParsableKey(idx.Key) {
return fmt.Errorf("instance index must be string or number")
} Type guard
func isValidIndexType(v cty.Value) bool {
return v.IsKnown() && !v.IsNull() && (v.Type() == cty.String || v.Type() == cty.Number)
} Try / catch
key, err := addrs.ParseInstanceKey(idx.Key)
if err != nil {
// re-surface as a config/source-range diagnostic so the user sees the location
return diags.Append(hclDiagnosticFromError(err))
} Prevention
- Never index resources with bool/list/object values.
- Validate traverse-index types before parsing addresses.
- Ensure codegen emits only string/number indices.
When it happens
Trigger: Returned at internal/addrs/instance_key.go:48 (default switch case). Callers include parse_ref.go:319/542/657, parse_target.go:270, action.go:488, and stacks address parsers (component.go:207, in_stack.go:189, removed.go:361) — all feeding a hcl.TraverseIndex.Key into ParseInstanceKey.
Common situations: A resource address literal with a non-string/number index, e.g. `aws_instance.web[true]` or an index expression that evaluates to a list/object. Programmatic address parsing (terraform address -target) with a malformed instance key. A stacks/component iteration using an unsupported key type. HCL produced by tooling that emits an invalid traverse index.
Related errors
- NewInstanceInfo cannot convert resource instance with %T ins
- empty state name
- Attempted to initialize pluggable state with an empty string
- missing state name
- the secret name %v is invalid, {validationErrors} This is a
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/0019e347a9c1a24b.
Report an issue: GitHub.