micro/go-micro · error

Invalid event returned from stroe

Error message

Invalid event returned from stroe

What it means

After reading raw records, evStore.Read unmarshals each record's Value bytes into an Event struct. This error wraps a json.Unmarshal failure, meaning a stored record's payload is not valid JSON for the Event schema. (Note the typo 'stroe' is in the library's message text.)

Source

Thrown at events/store.go:72

		o(&options)
	}

	// execute the request
	recs, err := s.store.Read(topic+joinKey,
		store.ReadPrefix(),
		store.ReadLimit(options.Limit),
		store.ReadOffset(options.Offset),
	)
	if err != nil {
		return nil, errors.Wrap(err, "Error reading from store")
	}

	// unmarshal the result
	result := make([]*Event, len(recs))
	for i, r := range recs {
		var e Event
		if err := json.Unmarshal(r.Value, &e); err != nil {
			return nil, errors.Wrap(err, "Invalid event returned from stroe")
		}
		result[i] = &e
	}

	return result, nil
}

// Write an event to the store
func (s *evStore) Write(event *Event, opts ...WriteOption) error {
	// parse the options
	options := WriteOptions{
		TTL: s.opts.TTL,
	}
	for _, o := range opts {
		o(&options)
	}

	// construct the store record

View on GitHub (pinned to 24529f1404)

Solutions

  1. Identify the offending record and check its JSON against the current Event struct
  2. Migrate or purge records written by the old schema version
  3. Use json tags and tolerant decoding (e.g. keep fields optional) to stay backward compatible
  4. Validate payload shape at write time to prevent corrupt entries
  5. Clear the topic's records if they are disposable and re-publish

Example fix

// before
type Event struct { ID string; Timestamp int64 } // old records store "time" as string
json.Unmarshal(r.Value, &e) // fails on legacy records
// after
type Event struct { ID string; Timestamp int64 }
var raw map[string]json.RawMessage
json.Unmarshal(r.Value, &raw)
// migrate legacy "time" field before decoding into Event
Defensive patterns

Strategy: type-guard

Validate before calling

func isValidEventJSON(b []byte) bool {
    var probe map[string]json.RawMessage
    return json.Unmarshal(b, &probe) == nil && probe["id"] != nil
}

Type guard

func safeDecodeEvent(b []byte) (*events.Event, error) {
    var e events.Event
    if err := json.Unmarshal(b, &e); err != nil {
        return nil, fmt.Errorf("skipping malformed record: %w", err)
    }
    return &e, nil
}

Try / catch

recs, err := evStore.Read(topic)
if err != nil {
    if strings.Contains(err.Error(), "Invalid event returned from stroe") {
        // skip/repair the malformed record instead of failing the whole read
        log.Printf("malformed record: %v", errors.Cause(err))
    }
    return err
}

Prevention

When it happens

Trigger: A record in the store was written by a different/older version of the library with an incompatible Event schema, the record bytes were corrupted, or the store backend returned non-JSON data under the topic prefix.

Common situations: Schema drift after upgrading the events package (renamed/retyped Event fields); manual edits or backups restoring incompatible records; a store shared between services writing different payload shapes under the same topic prefix.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/6b116db78afb4e6a. Report an issue: GitHub.