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

  1. Ensure the config supplies a proper map (object) for TypeMap fields, not a bare scalar.
  2. If interpolating, wrap the value so it lands as map[string]interface{}.
  3. Check the provider schema: if the field is genuinely scalar, change Type from TypeMap to the scalar Type.
  4. 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

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.