Expected Behavior
A single actor whose serialized form cannot be decoded by a caller should cost that caller that
actor — an error naming it, a skipped row, a partial response with a warning. Losing the view of
every actor in the atespace is disproportionate to the fault.
Actual Behavior
ListActors returns a single message containing every actor, so any decode failure on any row fails
the entire response for every caller. Observed as:
Error: failed to list actors: rpc error: code = Internal desc = grpc:
failed to unmarshal the received message: string field contains invalid UTF-8
There is nothing in the error identifying the actor, so recovery starts with an unbounded search
across the atespace. In the case that produced this (see the schema issue above), the trigger was
one running actor among many, and the only way to find it was to decode the wire bytes by hand.
Steps to Reproduce the Problem
- Produce any actor whose row a given client cannot decode. The reproducible route today is the tag
reuse described in the linked issue: an old client plus one RUNNING actor with a
worker_assignment of 128 bytes or more.
- Call
ListActors for that atespace, e.g. kubectl-ate get actors -a <atespace>.
- Observe that the response fails entirely, that no other actor is listed, and that nothing in the
error names the responsible actor.
Specifications
- Version:
main at ea3bdc32 (2026-09-02); rpc ListActors at ateapi.proto:102, response
ListActorsResponse at :1588.
- Platform: any.
Notes
Worth fixing on its own merits regardless of the schema issue: any future decode-affecting change,
on any field, inherits this blast radius. Pagination already exists on this RPC, so per-page partial
success plus a per-row error list is a natural shape.
Related to #1396
Expected Behavior
A single actor whose serialized form cannot be decoded by a caller should cost that caller that
actor — an error naming it, a skipped row, a partial response with a warning. Losing the view of
every actor in the atespace is disproportionate to the fault.
Actual Behavior
ListActorsreturns a single message containing every actor, so any decode failure on any row failsthe entire response for every caller. Observed as:
There is nothing in the error identifying the actor, so recovery starts with an unbounded search
across the atespace. In the case that produced this (see the schema issue above), the trigger was
one running actor among many, and the only way to find it was to decode the wire bytes by hand.
Steps to Reproduce the Problem
reuse described in the linked issue: an old client plus one RUNNING actor with a
worker_assignmentof 128 bytes or more.ListActorsfor that atespace, e.g.kubectl-ate get actors -a <atespace>.error names the responsible actor.
Specifications
mainatea3bdc32(2026-09-02);rpc ListActorsatateapi.proto:102, responseListActorsResponseat:1588.Notes
Worth fixing on its own merits regardless of the schema issue: any future decode-affecting change,
on any field, inherits this blast radius. Pagination already exists on this RPC, so per-page partial
success plus a per-row error list is a natural shape.
Related to #1396