micro/go-micro · error
ErrEncodingMessage
ErrEncodingMessage
Error message
error encoding message
What it means
ErrEncodingMessage is returned by events.Publish when the message option cannot be encoded into the event payload. The events layer marshals messages (e.g. to JSON) before publishing; an unsupported or unencodable value produces this sentinel error.
Source
Thrown at events/events.go:21
import (
"encoding/json"
"errors"
"time"
)
var (
// DefaultStream is the default events stream implementation
DefaultStream Stream
// DefaultStore is the default events store implementation
DefaultStore Store
)
var (
// ErrMissingTopic is returned if a blank topic was provided to publish
ErrMissingTopic = errors.New("missing topic")
// ErrEncodingMessage is returned from publish if there was an error encoding the message option
ErrEncodingMessage = errors.New("error encoding message")
)
// Stream is an event streaming interface
type Stream interface {
Publish(topic string, msg interface{}, opts ...PublishOption) error
Consume(topic string, opts ...ConsumeOption) (<-chan Event, error)
}
// Store is an event store interface
type Store interface {
Read(topic string, opts ...ReadOption) ([]*Event, error)
Write(event *Event, opts ...WriteOption) error
}
type AckFunc func() error
type NackFunc func() error
// Event is the object returned by the broker when you subscribe to a topicView on GitHub (pinned to 24529f1404)
Solutions
- Inspect the underlying error (errors.Is/Unwrap) to find which field failed to encode.
- Ensure published messages are plain serializable data: exported fields, no channels/funcs/cycles; convert to a DTO struct if needed.
- If using a custom MarshalJSON, fix or guard it so it never returns an error for valid domain states.
- Log the message type and a sanitized snapshot when this sentinel occurs to identify the offending payload quickly.
Example fix
// before
stream.Publish("orders", struct {
ctx context.Context
}{} ) // unexported/non-serializable
// after
type OrderEvent struct {
ID string `json:"id"`
}
stream.Publish("orders", OrderEvent{ID: id}) Defensive patterns
Strategy: validation
Validate before calling
if _, err := json.Marshal(msg); err != nil {
return fmt.Errorf("message not publishable: %w", err)
} Type guard
func serializable(v interface{}) bool {
_, err := json.Marshal(v)
return err == nil
} Try / catch
if err := stream.Publish(topic, msg); err != nil {
if errors.Is(err, events.ErrEncodingMessage) {
return fmt.Errorf("publish: cannot encode %T: %w", msg, err)
}
return err
} Prevention
- Publish only DTO structs with exported, JSON-serializable fields
- Keep channels, contexts, funcs, and cycles out of event payloads
- Add a marshal smoke test for every event type in CI
When it happens
Trigger: Publishing a message the configured codec cannot marshal — e.g. a value containing channels, funcs, cyclic references, or a type whose MarshalJSON returns an error — when calling Stream.Publish(topic, msg, opts...).
Common situations: Publishing structs with unexported-only fields producing empty/invalid JSON; passing context.Context or other non-serializable values embedded in the payload; a custom marshaler returning an error (e.g. time.Time in an invalid state).
Related errors
- ErrMissingTopic
- ErrEncodingToken
- ErrInvalidMessage
- failed to marshal request: %w
- failed to marshal stream request: %w
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/a1fde887f62a1352.
Report an issue: GitHub.