hashicorp/terraform · error
attribute schema is nil
Error message
attribute schema is nil
What it means
Raised by Attribute.InternalValidate when called on a nil *Attribute receiver. This is the public entry point at internal_validate.go:131; a nil receiver means the caller asked to validate an attribute that was never constructed.
Source
Thrown at internal/configs/configschema/internal_validate.go:133
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: Computed cannot be used when MinItems > 0", prefix, name))
}
default:
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: invalid nesting mode %s", prefix, name, blockS.Nesting))
}
subPrefix := prefix + name + "."
multiErr = errors.Join(multiErr, blockS.Block.internalValidate(subPrefix))
}
return multiErr
}
// InternalValidate returns an error if the receiving attribute and its child
// schema definitions have any inconsistencies with the documented rules for
// valid schema.
func (a *Attribute) InternalValidate(name string) error {
if a == nil {
return fmt.Errorf("attribute schema is nil")
}
return a.internalValidate(name, "")
}
func (a *Attribute) internalValidate(name, prefix string) error {
var err error
/* FIXME: this validation breaks certain existing providers and cannot be enforced without coordination.
if !validName.MatchString(name) {
err = errors.Join(err, fmt.Errorf("%s%s: name may contain only lowercase letters, digits and underscores", prefix, name))
}
*/
if !a.Optional && !a.Required && !a.Computed {
err = errors.Join(err, fmt.Errorf("%s%s: must set Optional, Required or Computed", prefix, name))
}
if a.Optional && a.Required {
err = errors.Join(err, fmt.Errorf("%s%s: cannot set both Optional and Required", prefix, name))
}View on GitHub (pinned to c9def3e214)
Solutions
- Guard the call site: if attr != nil { attr.InternalValidate(name) }.
- Fix the upstream construction so the *Attribute is always populated before validation.
- Prefer validating the whole Block via Block.InternalValidate, which already skips nil entries with a clearer per-name message (error 838).
Example fix
// before
attr := attrs[key] // nil if absent
if err := attr.InternalValidate(key); err != nil { return err }
// after
attr, ok := attrs[key]
if !ok || attr == nil { continue }
if err := attr.InternalValidate(key); err != nil { return err } Defensive patterns
Strategy: type-guard
Validate before calling
if attr == nil {
return fmt.Errorf("attribute %q is nil before validate", name)
}
return attr.InternalValidate(name) Type guard
func isNonNilAttribute(a *configschema.Attribute) bool { return a != nil } Prevention
- Prefer Block.InternalValidate, which skips nil attribute entries with a clearer per-name message.
- Nil-check any *Attribute retrieved from a map before calling methods on it.
- Construct attributes via helpers that return an error rather than nil on failure.
When it happens
Trigger: Code calls someAttr.InternalValidate(name) where someAttr is a nil *Attribute. The nil check at line 132 returns the error before any field access.
Common situations: Lookups like attrs["missing_key"] returning nil and being validated without a nil check; refactoring that moved attribute construction into a helper returning nil on an error path; deserialization producing nil pointers for omitted keys.
Related errors
- top-level block schema is nil
- %s%s: attribute schema is nil
- %s%s: block schema is nil
- %s%s: must set Optional, Required or Computed
- %s%s: cannot set both Optional and Required
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/f7523de60768a7a5.
Report an issue: GitHub.