hashicorp/terraform · error

%s%s: NestingSet attributes may not contain attributes of ct

Error message

%s%s: NestingSet attributes may not contain attributes of cty.DynamicPseudoType

What it means

Raised when an Attribute whose NestedType uses NestingSet contains cty.DynamicPseudoType in its implied type. This is the attribute-level analogue of error 822: cty sets need a concrete hashable element type, so dynamic typing inside a set is unsupported. The validator at internal_validate.go:174-176 calls a.ImpliedType().HasDynamicTypes() and rejects the schema.

Source

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

	if a.Type != cty.NilType {
		if a.NestedType != nil {
			err = errors.Join(fmt.Errorf("%s: Type and NestedType cannot both be set", name))
		}
	}

	if a.NestedType != nil {
		switch a.NestedType.Nesting {
		case NestingSingle, NestingMap, NestingGroup:
			// no validations to perform
		case NestingList, NestingSet:
			if a.NestedType.Nesting == NestingSet {
				ety := a.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.
					err = errors.Join(err, fmt.Errorf("%s%s: NestingSet attributes may not contain attributes of cty.DynamicPseudoType", prefix, name))
				}
				if a.NestedType.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.
					err = errors.Join(err, fmt.Errorf("%s%s: NestingSet attributes may not contain WriteOnly attributes", prefix, name))
				}
			}
		default:
			err = errors.Join(err, fmt.Errorf("%s%s: invalid nesting mode %s", prefix, name, a.NestedType.Nesting))
		}
		for name, attrS := range a.NestedType.Attributes {
			if attrS == nil {
				err = errors.Join(err, fmt.Errorf("%s%s: attribute schema is nil", prefix, name))
				continue
			}
			err = errors.Join(err, attrS.internalValidate(name, prefix))
		}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Switch NestedType.Nesting to NestingList if dynamic-typed elements are required.
  2. Constrain the dynamic nested attribute to a concrete hashable type (e.g. cty.Map(cty.String)).
  3. Model arbitrary key/value data as a map rather than a set of dynamic objects.

Example fix

// before
"items": {
    Optional: true,
    NestedType: &Object{
        Nesting: NestingSet,
        Attributes: map[string]*Attribute{"data": {Type: cty.DynamicPseudoType, Optional: true}},
    },
}

// after
"items": {
    Optional: true,
    NestedType: &Object{
        Nesting: NestingList,
        Attributes: map[string]*Attribute{"data": {Type: cty.DynamicPseudoType, Optional: true}},
    },
}
Defensive patterns

Strategy: validation

Validate before calling

func assertNestedSetNotDynamic(a *configschema.Attribute) error {
    if a.NestedType == nil || a.NestedType.Nesting != configschema.NestingSet { return nil }
    if a.ImpliedType().HasDynamicTypes() {
        return fmt.Errorf("NestingSet attribute may not contain cty.DynamicPseudoType")
    }
    return nil
}

Prevention

When it happens

Trigger: An Attribute with NestedType.Nesting == NestingSet whose nested Attributes include one with Type=cty.DynamicPseudoType (or any descendant resolving to dynamic). The NestingSet branch at line 174 evaluates HasDynamicTypes() at line 176 and it returns true.

Common situations: Using a structural set attribute (NestedType+NestingSet) to model deduped arbitrary objects; converting a NestedType list to a set without removing a dynamic 'metadata' field; framework-generated schemas defaulting unknown subfields to dynamic.

Related errors


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