Pingerchips LogoPingerchips
Wire Protocol

Errors & sequencing

Every error string the wire returns, and the ordering guarantees you can rely on.

Error shape

Channel repliesphx_reply with status: "error":

{ "status": "error", "response": { "reason": "<string>" } }

HTTP — capability issuer, chat REST, dashboard:

{ "errors": [{ "status": "401", "title": "Unauthorized", "detail": "..." }] }

HTTP — Durable Objects operation failures:

{ "error": "<string>" }

Channel join errors

reasonChannelCause
invalid tokenanycapability token bad, expired, wrong signature, or bound to a different socket
forbidden: missing channel:subscribe:{channel}PubSubtoken doesn't grant subscribe on this channel
forbidden: missing object:read:{type}/{key}Durable Objecttoken doesn't grant read on this object
forbidden: missing chat:subscribe:{threadId}Chattoken doesn't grant subscribe on this thread
auth required for private/presence channelsPubSubprivate-* / presence-* join with no auth
auth required for durable object channelsDurable Objectno auth and no app_secret
auth requiredChatapp has enable_user_authentication = 1 and no token
invalid app_secretDurable Objectwrong app_secret
invalid secretChatagent join with a wrong secret
app_key mismatchanytopic's {appKey} segment ≠ the connected app
invalid topic formatanymalformed topic

Channel push errors

reasonPushCause
Client messages are disabledPubSub publishapp has Enable Client Messages off
Channel mode does not permit publishingPubSub publishpublishing on a channel whose token/mode forbids it
Rate limit exceededPubSub publishover max_client_events_per_sec
Validation failed: {detail}PubSub publishpayload failed channel validation (name / size limits)
forbidden: missing {verb}Chat pushprincipal lacks the capability the push needs
not_foundChat cancelrunId not in this thread
already_endedChat cancel / agent run:endrun is already terminal
forbiddenChat cancelnot the run owner, and no publish:cancel_any
invalid_stateagent run:suspend / run:resumerun not in the required prior state
archive_unavailableChat load_olderan archived page couldn't be fetched
writes must go through the server SDKDurable Object channelany client push (the channel is read-only)

HTTP errors

StatusWhereCause
401any server callmissing / wrong X-App-Key / X-App-Secret, or the path app_id isn't the authenticated app
422POST /api/authmissing socket_id / client_id, empty capability list, or a malformed capability string
422Durable Object opincrement on a non-numeric slot, append on a non-list, bad transaction op
404Durable Objectroute not matched, or GET /{slot} for an unset slot
429trigger / publishover max_backend_events_per_sec

Sequencing guarantees

Cursors

ProductCursorMonotonicTotal order
PubSubserial (per channel)yesyes, within a channel
Durable Objectslog_id (per object)yesyes, across all subscribers
Chatlog_id (per thread)yesyes, across all subscribers
Spacesno ordering; pure relay

Guarantees

  • A snapshot reflects state exactly at its log_id. Live events resume at log_id + 1 — nothing between is dropped or duplicated.
  • after_serial / after_log_id replay is exact and in order, delivered before the snapshot (Durable Objects, Chat) or before live delivery (PubSub).
  • Chat: run:end is always emitted before its companion batch. The GC compaction batch is atomic — all four slot changes arrive together.
  • Durable Objects: a batch from set_all / transaction is atomic.
  • PubSub: message order within a channel matches publish order; across channels there is no ordering.

Not guaranteed

  • Ordering of events across different channels / objects / threads on one socket.
  • Delivery of Spaces events missed while disconnected.
  • Live presence:join / presence:leave on ephemeral-* channels (not yet broadcast — see Spaces).

On this page