BigPizzaV3/CodexPlusPlus · error · anyhow::Error
registration type must be register
Error message
registration type must be register
What it means
After JSON-parsing the first WebSocket message, the relay validates that RegisterMessage.message_type equals the literal "register". Any other message_type value bails, because the relay only accepts registration frames on a fresh connection.
Solutions
- Set message_type to exactly "register" in the first message
- Update the client library to the current relay protocol version
- Send only the registration frame first; send other messages after registration succeeds
Example fix
// before
{ "message_type": "Register", "room": "r1", "token": "t", "role": "client" }
// after
{ "message_type": "register", "room": "r1", "token": "t", "role": "client" } Defensive patterns
Strategy: validation
Validate before calling
if (reg.message_type !== 'register') throw new Error('message_type must be "register"'); Type guard
const isRegisterMessage = (m: unknown): m is RegisterMessage => typeof m === 'object' && m !== null && (m as any).message_type === 'register';
Try / catch
ws.onclose = (e) => { if (String(e.reason).includes('registration type')) fixMessageTypeAndReconnect(); }; Prevention
- Use a shared protocol constant for message_type
- Keep client and relay protocol versions in sync
- Unit-test registration payload serialization
When it happens
Trigger: Sending a first frame that is valid JSON but whose message_type field is not "register" (e.g. "Register", "reg", or a data/chat message) during handle_websocket_connection -> parse_registration (main.rs ~365).
Common situations: Client sends a chat/data message before registering; case mismatch "Register" vs "register"; outdated client using an older protocol message_type value.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/0b90c76bd046a86b.
Report an issue: GitHub.
Appendix: source
Thrown at apps/codex-plus-mobile-relay/src/main.rs:365
);
stream.write_all(response.as_bytes()).await?;
stream.write_all(&body).await?;
stream.shutdown().await?;
Ok(())
}
fn parse_registration(message: Message) -> anyhow::Result<Registration> {
let text = match message {
Message::Text(text) => text.to_string(),
Message::Binary(bytes) => {
String::from_utf8(bytes.to_vec()).context("binary registration must be utf-8 json")?
}
_ => bail!("first message must be registration json"),
};
let registration: RegisterMessage =
serde_json::from_str(&text).context("registration is not valid json")?;
if registration.message_type != "register" {
bail!("registration type must be register");
}
if registration.room.trim().is_empty() {
bail!("room is required");
}
if registration.token.trim().is_empty() {
bail!("token is required");
}
let role = Role::from_str(®istration.role).context("role must be host or client")?;
Ok(Registration {
role,
room: registration.room,
token: registration.token,
})
}
fn registration_from_uri(path: &str, query: Option<&str>) -> Option<Registration> {
let query = query?;
let role = match path {View on GitHub (pinned to b1ed92e5e4)