hashicorp/terraform · critical
unknown type: %#v
Error message
unknown type: %#v
What it means
A panic in `ConfigFieldReader.readMap` (internal/legacy/helper/schema/field_reader_config.go:229), default branch of a Go type switch over the raw map value `mraw`. The reader expects the raw value to be one of: string, []interface{}, []map[string]interface{}, map[string]interface{}, or nil. Any other Go type for a map field's raw config value panics with 'unknown type: %#v'. Unlike the Type-based panics, this is triggered by unexpected runtime data shape rather than a bad schema Type.
Source
Thrown at internal/legacy/helper/schema/field_reader_config.go:229
result[ik] = v
}
}
case map[string]interface{}:
for ik := range m {
key := fmt.Sprintf("%s.%s", k, ik)
if r.Config.IsComputed(key) {
computed = true
break
}
v, _ := r.Config.Get(key)
result[ik] = v
}
case nil:
// the map may have been empty on the configuration, so we leave the
// empty result
default:
panic(fmt.Sprintf("unknown type: %#v", mraw))
}
err := mapValuesToPrimitive(k, result, schema)
if err != nil {
return FieldReadResult{}, nil
}
var value interface{}
if !computed {
value = result
}
return FieldReadResult{
Value: value,
Exists: true,
Computed: computed,
}, nil
}View on GitHub (pinned to c9def3e214)
Solutions
- Ensure the config supplies a proper map (object) for TypeMap fields, not a bare scalar.
- If interpolating, wrap the value so it lands as map[string]interface{}.
- Check the provider schema: if the field is genuinely scalar, change Type from TypeMap to the scalar Type.
- Report a parser/provider bug if the config is valid but the raw value is malformed.
Example fix
null
Defensive patterns
Strategy: type-guard
Validate before calling
// Go (provider/test): ensure map fields receive map-shaped config values
func isMapLike(v interface{}) bool {
switch v.(type) {
case string, []interface{}, []map[string]interface{}, map[string]interface{}, nil:
return true
}
return false
} Type guard
// Go: narrow the raw map value before the reader's type switch
switch mraw.(type) {
case string, []interface{}, []map[string]interface{}, map[string]interface{}, nil:
// safe to read
default:
return FieldReadResult{}, fmt.Errorf("unexpected raw type %T for map field", mraw)
} Try / catch
// Go: recover from the readMap panic and return a controlled error
defer func() {
if r := recover(); r != nil {
res = FieldReadResult{}
err = fmt.Errorf("invalid map config value: %v", r)
}
}()
res, err = r.readMap(k, schema) Prevention
- Supply proper object/map values for TypeMap fields, not bare scalars.
- Wrap interpolated values so they resolve to map[string]interface{}.
- If a field is genuinely scalar, change its schema Type away from TypeMap.
- Add config-acceptance tests covering map field shapes.
When it happens
Trigger: Reading a TypeMap field from config where the underlying raw value (from the config parser) is a Go type the reader does not handle — e.g. a float64/bool/int raw value landing where a map was expected, or a custom type returned by an interpolation/parser bug.
Common situations: Config interpolation producing an unexpected scalar where a map was declared; provider schema declaring TypeMap but config supplying a single scalar value; parser/config-source bugs returning a non-map Go value; mixed computed/interpolated map values.
Related errors
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/13880d32e64e96b9.
Report an issue: GitHub.