apache/beam · error

Nested type in " " not permitted in concrete types.

Error message

Nested type in %v "%v" not permitted in concrete types.

What it means

When validating array, slice, or pointer types, isConcrete recursively checks the element type; on failure it wraps the error with 'Nested type in <kind> ...' to identify the containing array/slice/pointer. It localizes the offending type within your element-type graph.

Solutions

  1. Follow the wrapped error chain to the leaf type and fix its kind (no chan/func/unsafe.Pointer/uintptr).
  2. Unexport offending fields so isConcrete skips them (private fields are ignored).
  3. Restructure pointer graphs into flat serializable records.
  4. Add a unit test calling typex.CheckConcrete on the element type to fail fast during development.

Example fix

// before
type Node struct {
    Next *Node
    Emit func(Event)
}

// after
type Node struct {
    NextID string
    EmitTarget string
}
Defensive patterns

Strategy: validation

Validate before calling

if err := typex.CheckConcrete(reflect.TypeOf(sliceElem)); err != nil {
    return fmt.Errorf("slice/ptr element type rejected: %w", err)
}

Type guard

func nestedSafe(t reflect.Type) bool {
    switch t.Kind() {
    case reflect.Array, reflect.Slice, reflect.Ptr:
        return typex.IsConcrete(t)
    }
    return true
}

Prevention

When it happens

Trigger: Element types like []*unsafe.Pointer-wrapped structs, []chan Event, [][]func(), or pointers to structs containing chan/func exported fields.

Common situations: Slices of records with callback fields; pointer-based object graphs (linked lists with func fields); test fixtures reused as pipeline element types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/2e84a9200cb66e5e. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/core/typex/class.go:150

		return errors.Errorf("Type \"%v\" of kind \"%v\" not permitted in concrete types. All types must be manageable.", t, t.Kind()) // no unmanageable types

	case reflect.Chan, reflect.Func:
		return errors.Errorf("Type \"%v\" of kind \"%v\" not permitted in concrete types. All types must be serializable.", t, t.Kind()) // no unserializable types

	case reflect.Map:
		err := isConcrete(t.Elem(), visited)
		if err == nil {
			err = isConcrete(t.Key(), visited)
		}
		if err != nil {
			err = errors.Wrapf(err, "Nested type in map \"%v\" not permitted in concrete types.", t)
		}
		return err

	case reflect.Array, reflect.Slice, reflect.Ptr:
		err := isConcrete(t.Elem(), visited)
		if err != nil {
			err = errors.Wrapf(err, "Nested type in %v \"%v\" not permitted in concrete types.", t.Kind(), t)
		}
		return err

	case reflect.Struct:
		for i := 0; i < t.NumField(); i++ {
			// We ignore private fields under the assumption that they are
			// either not needed or will be coded manually. For combiner
			// accumulators, we need types that need non-trivial coding. Also,
			// Go serialization schemes in general ignore private fields.

			f := t.Field(i)
			if len(f.Name) > 0 {
				r, _ := utf8.DecodeRuneInString(f.Name)
				if unicode.IsUpper(r) {
					err := isConcrete(f.Type, visited)
					if err != nil {
						return errors.Wrapf(err, "Nested type in struct \"%v\" not permitted in concrete types.", t)
					}

View on GitHub (pinned to 12126d8942)