wavetermdev/waveterm · error

atom %s: %s

Error message

atom %s: %s

What it means

Top-level variant of makeAtomError with no parent context: the message applies to the atom type itself rather than a nested field. ValidateAtomType emits it when the atom's own type is nil or fails a top-level serialization check.

Source

Thrown at tsunami/util/util.go:150

		return true
	}
	if t.Kind() != reflect.Pointer {
		pt := reflect.PointerTo(t)
		return pt.Implements(jsonMarshalerT) || pt.Implements(textMarshalerT)
	}
	return false
}

func ValidateAtomType(t reflect.Type, atomName string) error {
	seen := make(map[reflect.Type]bool)
	return validateAtomTypeRecursive(t, seen, atomName, "")
}

func makeAtomError(atomName string, parentName string, message string) error {
	if parentName != "" {
		return fmt.Errorf("atom %s: in %s: %s", atomName, parentName, message)
	}
	return fmt.Errorf("atom %s: %s", atomName, message)
}

func validateAtomTypeRecursive(t reflect.Type, seen map[reflect.Type]bool, atomName string, parentName string) error {
	if t == nil {
		return makeAtomError(atomName, parentName, "nil type")
	}

	if seen[t] {
		return nil
	}
	seen[t] = true

	// Check if type implements json.Marshaler or encoding.TextMarshaler
	if implementsJSON(t) {
		return nil
	}

	// Allow time.Time explicitly

View on GitHub (pinned to a4447c1563)

Solutions

  1. Pass a concrete type: use reflect.TypeOf((*T)(nil)).Elem() instead of a nil reflect.Type.
  2. Make the atom type implement json.Marshaler or encoding.TextMarshaler.
  3. Ensure the atom's root type is a serializable struct/map/primitive; move unsupported members behind a marshaler.

Example fix

// before
util.ValidateAtomType(nil, "mynote") // atom mynote: nil type
// after
typ := reflect.TypeOf((*NoteType)(nil)).Elem()
util.ValidateAtomType(typ, "mynote")
Defensive patterns

Strategy: validation

Validate before calling

typ := reflect.TypeOf((*MyAtom)(nil)).Elem()
if typ == nil {
    return errors.New("atom type must be non-nil")
}
if err := util.ValidateAtomType(typ, "myatom"); err != nil { ... }

Try / catch

if err := util.ValidateAtomType(typ, name); err != nil {
    if strings.HasPrefix(err.Error(), "atom "+name+": nil type") {
        return fmt.Errorf("developer error: nil reflect.Type passed for atom %s", name)
    }
    return err
}

Prevention

When it happens

Trigger: util.ValidateAtomType(nil, "atomname") (nil type), or validating an atom whose top-level type is not JSON/Text-marshalable and not otherwise whitelisted (not time.Time, chan/func at the root, etc.).

Common situations: Registering a new atom with reflect.TypeOf on a nil-typed value (uninitialized generic or nil pointer without Elem); changing an atom's type to something non-serializable like a func.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/ab827c09c884bbac. Report an issue: GitHub.