hashicorp/terraform · error
%s%s: block schema is nil
Error message
%s%s: block schema is nil
What it means
A nil entry exists in a Block's BlockTypes map (b.BlockTypes[name] == nil, checked at line 50). Analogous to 809 but for nested blocks; the validator skips recursion (`continue`) and records the error. Means a nested-block placeholder was left nil.
Source
Thrown at internal/configs/configschema/internal_validate.go:51
multiErr = errors.Join(multiErr, fmt.Errorf("top-level block: DeprecationMessage must not be set when Deprecated is false"))
}
for name, attrS := range b.Attributes {
if attrS == nil {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: attribute schema is nil", prefix, name))
continue
}
multiErr = errors.Join(multiErr, attrS.internalValidate(name, prefix))
// all attributes within a computed block must also be computed
if b.Computed && !attrS.Computed {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: all attributes within computed blocks must also be computed", prefix, name))
}
}
for name, blockS := range b.BlockTypes {
if blockS == nil {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: block schema is nil", prefix, name))
continue
}
if _, isAttr := b.Attributes[name]; isAttr {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: name defined as both attribute and child block type", prefix, name))
} else if !validName.MatchString(name) {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: name may contain only lowercase letters, digits and underscores", prefix, name))
}
if !blockS.Deprecated && blockS.DeprecationMessage != "" {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: DeprecationMessage must not be set when Deprecated is false", prefix, name))
}
if blockS.MinItems < 0 || blockS.MaxItems < 0 {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems and MaxItems must both be greater than zero", prefix, name))
}
// any nested blocks within a computed block must also be computed
if b.Computed && !blockS.Computed {View on GitHub (pinned to c9def3e214)
Solutions
- Provide a full *NestedBlock (with a non-nil inner Block and a valid Nesting mode) for every key.
- Omit the key if the nested block shouldn't exist.
Example fix
// before
BlockTypes: map[string]*configschema.NestedBlock{
"settings": nil,
}
// after
BlockTypes: map[string]*configschema.NestedBlock{
"settings": {Nesting: configschema.NestingSingle, Block: configschema.Block{Attributes: map[string]*configschema.Attribute{"x": {Type: cty.String, Optional: true}}}},
} Defensive patterns
Strategy: validation
Validate before calling
for k, nb := range block.BlockTypes {
if nb == nil { return fmt.Errorf("nested block %q is nil", k) }
} Prevention
- Never store nil in BlockTypes; omit the entry instead.
- Validate nested-block construction returns a populated *NestedBlock before insertion.
When it happens
Trigger: Building BlockTypes with `"settings": nil` or assigning a nil *NestedBlock from a helper that didn't populate it.
Common situations: Generated schemas, conditional nested-block construction returning nil, refactor leftovers.
Related errors
- top-level block schema is nil
- %s%s: attribute schema is nil
- top-level block: DeprecationMessage must not be set when Dep
- %s%s: all attributes within computed blocks must also be com
- %s%s: name defined as both attribute and child block type
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/76dd6b11beb13f5a.
Report an issue: GitHub.