Listeners
Errors from the listeners: block — cross-stream event subscriptions.
12 error codes in this section.
VERR_LISTENER_EVENT_NOT_FOUND
Listener references unknown event. A listener’s on: references an event type that is not registered in the event registry.
Impact: Listener is dead — it will never fire.
listeners:
update_user:
on: OrderShipped # not in events# Register OrderShipped in app.causet, or use the correct event name.VERR_LISTENER_EMPTY_MUTATE
Listener mutate block is empty. A listener’s mutate: block is present but contains no operations.
Impact: Listener fires but makes no changes — silent no-op.
listeners:
update_user:
on: OrderPlaced
mutate: [] # emptylisteners:
update_user:
on: OrderPlaced
mutate:
- entity: user
ops:
- op: add
path: /order_count
value: 1VERR_LISTENER_INVALID_OP
Invalid op in listener mutation. A listener mutation uses an op that is not allowed in listeners. Listeners may only mutate entity state, not emit events.
Impact: Listener cannot fire; entity state is not updated.
mutate:
- entity: user
ops:
- op: emit # not allowed in listeners
event_type: UserUpdatedmutate:
- entity: user
ops:
- op: add
path: /order_count
value: 1VERR_LISTENER_FIELD_NOT_FOUND
Listener mutation targets nonexistent field. A listener mutation references a field that does not exist on the target entity schema.
Impact: Mutation fails; entity state is not updated.
ops:
- op: set
path: /last_seen_at # field not in entity schema# Add 'last_seen_at' to the target entity's field definitions first.VERR_LISTENER_OP_TYPE_MISMATCH
Listener op incompatible with field type. A listener mutation op is incompatible with the target field’s declared type.
Impact: Mutation throws at runtime; entity state is not updated.
# username is type: string
ops:
- op: add
path: /username
value: 1 # add on string field# Use op: set for string fields, op: add/sub only for numeric fields.VERR_LISTENER_INVALID_TARGET
Listener target references undefined resolve alias. A listener mutation targets an entity via an alias not declared in the listener’s resolve: block.
Impact: Mutation cannot resolve its target entity; it is silently skipped.
mutate:
- entity: follower # 'follower' not in resolve:
ops: []# Add 'follower' to the listener's resolve: block.VERR_LISTENER_DUPLICATE_ALIAS
Duplicate listener resolve alias. The same alias is defined twice in a listener’s resolve: block.
Impact: Second definition overrides first; listener resolves the wrong entity.
resolve:
user: { ... }
user: { ... } # duplicate# Use unique alias names in the resolve: block.VERR_LISTENER_INVALID_LOOKUP
Invalid lookup in listener resolve. A listener resolve: lookup expression is malformed — wrong syntax or missing required parts.
Impact: Listener cannot resolve its target; all mutations are skipped.
resolve:
user: lookup(users) # missing ID argumentresolve:
user: lookup(users, event.payload.user_id)VERR_LISTENER_RESOLVE_STREAM_NOT_FOUND
Listener resolve references unknown stream. A listener resolve: block references a stream name that does not match any defined state.
Impact: Listener cannot resolve its target entity.
resolve:
user: lookup(unknown_stream, event.payload.user_id)# Ensure the stream name matches a defined state name.VERR_LISTENER_CIRCULAR_CHAIN
Circular listener event chain. A listener chain forms a cycle: event A triggers listener emitting event B, which triggers a listener emitting event A.
Impact: Infinite loop at runtime; Kafka consumer stalls.
# EventA → ListenerA emits EventB → ListenerB emits EventA# Redesign the listener chain to form a DAG (no cycles).VERR_EMIT_CIRCULAR_CHAIN
Circular action-emit chain. An action emits an event that, through listeners and routing, eventually triggers the same action again.
Impact: Infinite loop at runtime; intent processing stalls.
# Action A → emit Event1 → listener → Action A# Add a termination condition or restructure the event flow to be acyclic.VERR_LISTENER_NON_DETERMINISTIC
Non-deterministic expression in listener. A listener mutation uses a non-deterministic expression (now(), random(), or external state).
Impact: Replay of the triggering event produces different state mutations.
ops:
- op: set
path: /updated_at
value: "#{ now() }" # non-deterministicops:
- op: set
path: /updated_at
value: "#{ event.ts }"