Skip to main content

Module reason_code

Module reason_code 

Source
Expand description

Stable refusal reason codes, and the band map that governs who mints them.

A refusal that travels back to a client carries a u16 reason code beside its human-readable message. The code is the part a program may branch on; the message is the part a person reads. More than one crate in this workspace mints such codes, and a client that hardcodes a number cannot see which crate minted it — so the numeric space is partitioned into bands, and the partition is recorded here, beside the codes it governs.

§The band map

BandOwnerCurrently minted in
0x00000x00FFprotocol layer — parse, negotiation, authProtocolError’s associated consts in the liminal crate, crates/liminal/src/protocol/error.rs:56-72 (0x00010x0009 in use)
0x01000x01FFserver layer — channel-roster refusalsthis module (CHANNEL_NOT_REGISTERED_CODE, CHANNEL_QUIESCED_CODE; the rest of the band is reserved for further roster refusals)
0xFFFFthe server’s undifferentiated errorSERVER_ERROR_CODE in liminal-server, minted privately in four modules: src/server/connection/apply.rs:26, src/server/connection/pending_reply.rs:51, src/server/connection/delivery.rs:45, src/server/connection/channel_registry.rs

The map is the fence. Two crates minting u16 reason codes with no shared registry collide eventually, and the collision is silent: a client reads a number that means one thing to the crate that sent it and another to the crate that documented it. A new code is minted by taking the next free value inside its layer’s band and recording it in the row above; a band that has no row here has no owner and may not be minted into.

Channel-roster refusals sit outside the protocol band deliberately. A name that is not on the roster is an application-layer statement about server state, not a parse, negotiation, or authentication failure; filing it under the protocol band would make that band mean nothing.

The codes live in this crate rather than beside the protocol-layer consts they neighbour numerically, because liminal-protocol is the crate a wire client actually depends on: liminal-sdk requires it unconditionally and takes liminal only as an optional dependency, so a code minted in liminal — or in liminal-server — is a code every SDK client would otherwise hardcode as a bare literal.

§Not the participant tag registry

crate::wire::ServerDiscriminant also occupies 0x0100..=0x0124, and crate::wire::ClientDiscriminant also occupies 0x0001..=0x0008. Those are a different u16 altogether: the discriminant field selecting a participant value inside a participant frame (see crate::outcome), not a refusal’s reason code. The two registries reuse numbers without colliding because they never share a field. Nothing in the band map above governs, reserves, or constrains that registry, and nothing in that registry reserves a reason code.

Constants§

CHANNEL_NOT_REGISTERED_CODE
The named channel is not on the server’s roster.
CHANNEL_QUIESCED_CODE
The named channel is on the roster but quiesced; the reason it was quiesced travels in the refusal’s message, not in this code.