wavetermdev/waveterm · error
atom %s: in %s: %s
Error message
atom %s: in %s: %s
What it means
makeAtomError builds a contextual error for ValidateAtomType failures. With a non-empty parentName it prefixes the message with both the atom name and the containing field path, produced while recursively validating that an atom's type is JSON-serializable (all fields marshalable, no invalid types like chan/func in the tree).
Source
Thrown at tsunami/util/util.go:148
func implementsJSON(t reflect.Type) bool {
if t.Implements(jsonMarshalerT) || t.Implements(textMarshalerT) {
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
}View on GitHub (pinned to a4447c1563)
Solutions
- Fix the type named in the 'in <parent>' part of the message: remove or replace the non-serializable field.
- Implement MarshalJSON (or encoding.TextMarshaler) on the offending type so validation accepts it.
- Wrap the field in a serializable type (e.g. store a channel identifier string instead of the channel itself).
Example fix
// before
type Atom struct { Events chan int `json:"events"` } // invalid
// after
type Atom struct { Events []int `json:"events"` }
// or: func (c ChanWrapper) MarshalJSON() ([]byte, error) { ... } Defensive patterns
Strategy: validation
Validate before calling
func checkSerializable(v any) error {
_, err := json.Marshal(v)
return err
} Try / catch
if err := util.ValidateAtomType(reflect.TypeOf(atom), "myatom"); err != nil {
return fmt.Errorf("atom registration rejected: %w", err)
} Prevention
- Avoid chan/func/unsafe.Pointer fields in atom structs
- Implement MarshalJSON on custom types used inside atoms
- Run ValidateAtomType in unit tests at package init so new fields are caught immediately
When it happens
Trigger: Calling util.ValidateAtomType(reflect.TypeOf(myStruct), "myatom") where a nested field (named in parentName) has a type that fails validation — e.g. contains a chan, func, or unsafe.Pointer field without a MarshalJSON/TextMarshaler implementation.
Common situations: Adding a new field to an atom struct that holds a channel, function value, or other non-serializable type; registering a new atom type with an unsupported nested struct.
Related errors
- atom %s: %s
- out parameter must be a pointer, got %v
- invalid AIMessage: %w
- part %d: text type requires non-empty text field
- failed to marshal backup metadata: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/925583224136490f.
Report an issue: GitHub.