hashicorp/terraform · error

: all attributes within computed blocks must also be…

Error message

%s%s: all attributes within computed blocks must also be computed

What it means

A Block has Computed set to true (the entire block is computed/derived), but one of its Attributes has Computed set to false. Terraform's consistency rule requires that if a block is computed, every attribute within it must also be computed — otherwise the schema is contradictory about whether values are user-settable.

Solutions

  1. Mark every attribute inside the computed block as Computed: true.
  2. Alternatively, if the block should allow user input, remove Computed: true from the block itself.
  3. Review the provider schema definition for the resource/data source and ensure consistency between block-level and attribute-level Computed flags.
  4. Add a unit test calling InternalValidate() to catch schema inconsistencies early.

Example fix

// before — computed block with non-computed attribute
&Block{
    Computed: true,
    Attributes: map[string]*Attribute{
        "value": {Type: String, Optional: true},  // ← not Computed
    },
}

// after — attribute also computed
&Block{
    Computed: true,
    Attributes: map[string]*Attribute{
        "value": {Type: String, Computed: true},
    },
}
Defensive patterns

Strategy: validation

Validate before calling

// Provider developers: enforce computed-propagation rule
func enforceComputedConsistency(b *configschema.Block) error {
    if !b.Computed {
        return nil
    }
    for name, attr := range b.Attributes {
        if attr != nil && !attr.Computed {
            return fmt.Errorf("attribute %q must be Computed because parent block is Computed", name)
        }
    }
    return nil
}

// Unit test gate:
func TestComputedBlockConsistency(t *testing.T) {
    if err := myResourceSchema().InternalValidate(); err != nil {
        t.Fatal(err)
    }
}

Prevention

When it happens

Trigger: Block.Computed == true but an attribute within it has Computed == false (and is not also Optional, depending on interpretation). Triggered during NewContext schema validation when a provider defines a computed nested block with user-settable fields inside.

Common situations: Provider developer marks a block as Computed (read-only, server-assigned) but forgets to mark individual attributes as Computed too. Migration from terraform-plugin-sdk where Computed semantics propagate differently. Schema was partially refactored — the block-level flag was set but attributes weren't updated. Misunderstanding of the computed-propagation rule.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/d2ee47ba428ac494. Report an issue: GitHub.

Appendix: source

Thrown at internal/configs/configschema/internal_validate.go:45

}

func (b *Block) internalValidate(prefix string) error {
	var multiErr error

	if prefix == "" && !b.Deprecated && b.DeprecationMessage != "" {
		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))
		}

View on GitHub (pinned to d32a084675)