hashicorp/terraform · critical

set item just set doesn't exist

Error message

set item just set doesn't exist

What it means

Panics in MapFieldWriter.setSet (field_writer_map.go:331) during the slice->set conversion path. Each list element is written to a temporary MapFieldWriter and immediately re-read with tempR.ReadField; if result.Exists is false the write/read round-trip is broken and it panics. This is an internal invariant, not a normal caller error.

Source

Thrown at internal/legacy/helper/schema/field_writer_map.go:331

		// Build the set by going over the list items in order and
		// hashing them into the set. The reason we go over the list and
		// not the `value` directly is because this forces all types
		// to become []interface{} (generic) instead of []string, which
		// most hash functions are expecting.
		s := schema.ZeroValue().(*Set)
		tempR := &MapFieldReader{
			Map:    BasicMapReader(tempW.Map()),
			Schema: tempSchemaMap,
		}
		for i := 0; i < v.Len(); i++ {
			is := strconv.FormatInt(int64(i), 10)
			result, err := tempR.ReadField(append(tempAddr, is))
			if err != nil {
				return err
			}
			if !result.Exists {
				panic("set item just set doesn't exist")
			}

			s.Add(result.Value)
		}

		value = s
	}

	// Clear any keys that match the set address first. This is necessary because
	// it's always possible and sometimes may be necessary to write to a certain
	// writer layer more than once with different set data each time, which will
	// lead to different keys being inserted, which can lead to determinism
	// problems when the old data isn't wiped first.
	w.clearTree(addr)

	if value.(*Set) == nil {
		w.result[k+".#"] = "0"
		return nil

View on GitHub (pinned to c9def3e214)

Solutions

  1. Verify the set field's Elem is &schema.Schema{...} or &schema.Resource{...}.
  2. If you supply a custom Set (hash) function, ensure it handles every concrete type the set will hold.
  3. Reproduce with TestResourceData/TestResourceDataRaw to confirm the value round-trips before exercising it in plan/apply.

Example fix

// before
"ports": { Type: schema.TypeSet, Elem: nil },
// after
"ports": { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeInt} },
Defensive patterns

Strategy: validation

Validate before calling

func setElemOk(s *schema.Schema) bool {
    if s.Type != schema.TypeSet { return true }
    switch s.Elem.(type) {
    case *schema.Schema, *schema.Resource: return true
    }
    return s.Set != nil // custom hash bypasses the round-trip path
}

Type guard

func isSchemaOrResource(v interface{}) bool {
    switch v.(type) {
    case *schema.Schema, *schema.Resource: return true
    }
    return false
}

Prevention

When it happens

Trigger: A TypeSet field fed a []interface{} value whose element type cannot round-trip through the flatmap writer/reader (e.g. Elem misconfigured as nil or an unexpected concrete type, or a custom Set hash function that writes elements under a code the reader cannot locate).

Common situations: Provider schema bugs where a set's Elem is nil, a bare ValueType, or a struct instead of &schema.Schema/&schema.Resource; or a custom Set func that mishandles a type.

Related errors


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