hashicorp/terraform · critical
invalid set element type
Error message
invalid set element type
What it means
Panics in Schema.ZeroValue (schema.go:352) when building a zero-value Set for a TypeSet that has no custom Set function. It hashes elements using s.Elem and only handles *Schema and *Resource; any other concrete Elem (nil, a ValueType, a struct) panics with 'invalid set element type'.
Source
Thrown at internal/legacy/helper/schema/schema.go:352
return nil, nil
}
// Returns a zero value for the schema.
func (s *Schema) ZeroValue() interface{} {
// If it's a set then we'll do a bit of extra work to provide the
// right hashing function in our empty value.
if s.Type == TypeSet {
setFunc := s.Set
if setFunc == nil {
// Default set function uses the schema to hash the whole value
elem := s.Elem
switch t := elem.(type) {
case *Schema:
setFunc = HashSchema(t)
case *Resource:
setFunc = HashResource(t)
default:
panic("invalid set element type")
}
}
return &Set{F: setFunc}
} else {
return s.Type.Zero()
}
}
func (s *Schema) finalizeDiff(d *terraform.ResourceAttrDiff, customized bool) *terraform.ResourceAttrDiff {
if d == nil {
return d
}
if s.Type == TypeBool {
normalizeBoolString := func(s string) string {
switch s {
case "0":
return "false"View on GitHub (pinned to c9def3e214)
Solutions
- Set Elem to &schema.Schema{Type: ...} or &schema.Resource{Schema: ...}.
- Alternatively provide a custom Set (hash) function, which bypasses this code path entirely.
- Lint provider schemas for TypeSet entries lacking a valid Elem.
Example fix
// before
"roles": { Type: schema.TypeSet, Elem: schema.TypeString },
// after
"roles": { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString} }, Defensive patterns
Strategy: type-guard
Validate before calling
for k, s := range r.Schema {
if s.Type == schema.TypeSet && s.Set == nil && !isSchemaOrResource(s.Elem) {
return fmt.Errorf("%s: TypeSet Elem must be *Schema or *Resource", k)
}
} Type guard
func isSchemaOrResource(v interface{}) bool {
switch v.(type) {
case *schema.Schema, *schema.Resource: return true
}
return false
} Prevention
- Never set Elem to a bare ValueType on a TypeSet.
- Provide a custom Set func if Elem cannot be a *Schema/*Resource.
- Lint provider schemas for TypeSet with invalid Elem.
When it happens
Trigger: Declaring a TypeSet Schema with Elem set to a non-Schema/non-Resource value (commonly `Elem: schema.TypeString` instead of `Elem: &schema.Schema{Type: schema.TypeString}`), or Elem left nil with no custom Set func, then accessing ZeroValue (e.g. GetOk/Get on an empty set).
Common situations: Provider authors confuse Elem (which must be &schema.Schema/&schema.Resource) with Type; or omit Elem entirely on a TypeSet.
Related errors
- missing field in set: %s.%s
- Unknown type: %#v
- set item just set doesn't exist
- Unknown validation type: %#v
- unknown value type in TypeMap %T
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/dd55d8c2e18c9cfc.
Report an issue: GitHub.