hashicorp/terraform · error
%s%s: NestingGroup blocks cannot be computed
Error message
%s%s: NestingGroup blocks cannot be computed
What it means
Raised when a nested block declared with NestingGroup mode also has Computed=true. NestingGroup is intended to model an always-present feature group whose attributes take default values when the block is omitted; because the group is never null and never user-supplied en bloc, marking it Computed is meaningless and contradicts the semantic contract of the mode. The validator at internal_validate.go:86 rejects this combination so providers cannot construct a self-contradictory schema. Use NestingSingle or an attribute with NestedType if the value truly comes from the provider.
Source
Thrown at internal/configs/configschema/internal_validate.go:86
// any nested blocks within a computed block must also be computed
if b.Computed && !blockS.Computed {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: all nested blocks within computed blocks must also be computed", prefix, name))
}
switch blockS.Nesting {
case NestingSingle:
switch {
case blockS.MinItems != blockS.MaxItems:
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems and MaxItems must match in NestingSingle mode", prefix, name))
case blockS.MinItems < 0 || blockS.MinItems > 1:
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems and MaxItems must be set to either 0 or 1 in NestingSingle mode", prefix, name))
}
case NestingGroup:
if blockS.MinItems != 0 || blockS.MaxItems != 0 {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems and MaxItems cannot be used in NestingGroup mode", prefix, name))
}
if blockS.Computed {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: NestingGroup blocks cannot be computed", prefix, name))
}
case NestingList, NestingSet:
if blockS.MinItems > blockS.MaxItems && blockS.MaxItems != 0 {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems must be less than or equal to MaxItems in %s mode", prefix, name, blockS.Nesting))
}
if blockS.Nesting == NestingSet {
ety := blockS.Block.ImpliedType()
if ety.HasDynamicTypes() {
// This is not permitted because the HCL (cty) set implementation
// needs to know the exact type of set elements in order to
// properly hash them, and so can't support mixed types.
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: NestingSet blocks may not contain attributes of cty.DynamicPseudoType", prefix, name))
}
if blockS.Block.ContainsWriteOnly() {
// This is not permitted because any marks within sets will
// be hoisted up the outer set value, so only the set itself
// can be WriteOnly.
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: NestingSet blocks may not contain WriteOnly attributes", prefix, name))View on GitHub (pinned to c9def3e214)
Solutions
- Remove Computed: true from the NestingGroup NestedBlock; the mode already guarantees the block is non-null with defaulted attributes.
- If the value must be provider-computed, switch Nesting to NestingSingle (single computed object) or replace the block with an Attribute whose NestedType is an Object.
- Search the schema definition for the offending block name and confirm only the intended flags remain after the migration.
Example fix
// before
BlockTypes: map[string]*NestedBlock{
"settings": {Nesting: NestingGroup, Block: Block{Computed: true, Attributes: ...}},
}
// after
BlockTypes: map[string]*NestedBlock{
"settings": {Nesting: NestingGroup, Block: Block{Attributes: ...}},
} Defensive patterns
Strategy: validation
Validate before calling
// before registering the schema, assert NestingGroup blocks are not Computed
func validateGroupBlocks(b *configschema.Block) error {
for name, nb := range b.BlockTypes {
if nb == nil { continue }
if nb.Nesting == configschema.NestingGroup && nb.Computed {
return fmt.Errorf("%s: NestingGroup cannot be Computed", name)
}
if err := validateGroupBlocks(&nb.Block); err != nil { return err }
}
return nil
} Type guard
func isComputedGroup(nb *configschema.NestedBlock) bool {
return nb != nil && nb.Nesting == configschema.NestingGroup && nb.Computed
} Prevention
- Call Block.InternalValidate() in provider TestProvider and unit tests so invalid schemas fail at test time, not runtime.
- When migrating a block's Nesting mode, always re-audit every other field on the NestedBlock (Computed, MinItems, MaxItems) for compatibility with the new mode.
- Keep a schema-construction helper per nesting mode so incompatible flag combinations cannot be expressed.
When it happens
Trigger: A provider schema defines a NestedBlock with Nesting: NestingGroup and simultaneously sets Computed: true on the same NestedBlock struct (the embedded Block.Computed field). InternalValidate walks BlockTypes, hits the NestingGroup case at line 81, and emits this error when blockS.Computed is true at line 85.
Common situations: Migrating a block from NestingSingle/NestingList to NestingGroup while leaving an old Computed=true flag set; copying a schema struct verbatim and changing only the Nesting field; modeling a remote API response that is always present but forgetting NestingGroup already guarantees non-null presence.
Related errors
- %s%s: all attributes within computed blocks must also be com
- %s%s: all nested blocks within computed blocks must also be
- %s%s: MinItems and MaxItems cannot be used in NestingGroup m
- %s%s: Computed cannot be used when MinItems > 0
- %s%s: must set Optional, Required or Computed
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/f1775a5f536cab69.
Report an issue: GitHub.