{"record":{"id":"2e1046d1392e587d","repo":"astrid-runtime/astrid","slug":"unexpected-response-shape-other-2e1046","errorCode":null,"errorMessage":"unexpected response shape: {other:?}","messagePattern":"unexpected response shape: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/pair_device.rs","lineNumber":153,"sourceCode":"    let body = into_result(resp)?;\n    match body {\n        AdminResponseBody::PairToken(issued) => {\n            if args.raw {\n                println!(\"{}\", issued.token);\n            } else {\n                println!(\n                    \"{} {} (principal: {}, scope: {}, label: {})\",\n                    Theme::success(\"issued\"),\n                    issued.token.bold(),\n                    issued.principal,\n                    scope_summary,\n                    issued.label.as_deref().unwrap_or(\"-\"),\n                );\n                println!(\"expires at unix epoch {}\", issued.expires_at_epoch);\n            }\n            Ok(ExitCode::SUCCESS)\n        },\n        other => anyhow::bail!(\"unexpected response shape: {other:?}\"),\n    }\n}\n\nasync fn run_list(args: ListArgs) -> Result<ExitCode> {\n    let principal = context::resolve_agent(args.principal.as_deref())?;\n    let mut client = connect_as_active_agent().await?;\n    let resp = client\n        .request(AdminRequestKind::PairDeviceList { principal })\n        .await\n        .context(\"auth.pair.list request failed\")?;\n    let body = into_result(resp)?;\n    match body {\n        AdminResponseBody::PairDeviceListed(devices) => {\n            if args.json {\n                println!(\"{}\", serde_json::to_string_pretty(&devices)?);\n            } else if devices.is_empty() {\n                println!(\"{}\", Theme::dimmed(\"no paired devices\"));\n            } else {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/pair_device.rs#L135-L171","documentation":"run_issue matches the AdminResponseBody returned for a pair-device issue request and only handles the expected issued-response variant; any other variant falls into the `other` catch-all and bails with the debug-formatted response. This indicates a protocol/shape mismatch between what the CLI requested and what the daemon replied with.","triggerScenarios":"Sending a PairDevice issue request whose response body is an AdminResponseBody variant other than the expected issued/credential variant — e.g. an error body, a list/revoked body, or a variant added by a newer daemon — reaching the `other => anyhow::bail!` arm in run_issue.","commonSituations":"CLI and daemon version skew (daemon returns a new response shape); request routed to the wrong IPC topic so an unrelated response arrives; daemon returned an error encoded as a different body variant; corrupted or mixed-up responses on a shared connection.","solutions":["Update the astrid CLI and daemon to matching versions so AdminResponseBody shapes agree.","Log the full `other` payload ({other:?}) and compare against the AdminResponseBody enum to identify the mismatched variant.","Confirm the request kind/topic maps to the pair-device issue response (not list/revoke).","Add an explicit match arm for the new variant if the daemon intentionally returns it."],"exampleFix":"// before\nother => anyhow::bail!(\"unexpected response shape: {other:?}\"),\n// after\nAdminResponseBody::Error { message } => anyhow::bail!(\"issue failed: {message}\"),\nother => anyhow::bail!(\"unexpected response shape: {other:?}\"),","handlingStrategy":"type-guard","validationCode":"// confirm the request/response kind pair before matching the body\nif !matches!(resp.kind(), AdminResponseKind::PairDeviceIssued) {\n    anyhow::bail!(\"pair-device issue request mismatched with response kind {:?}\", resp.kind());\n}","typeGuard":"fn as_issue_response(body: &AdminResponseBody) -> Option<&PairDeviceIssued> {\n    match body {\n        AdminResponseBody::PairDeviceIssued(i) => Some(i),\n        _ => None,\n    }\n}","tryCatchPattern":"match run_issue(args).await {\n    Ok(code) => code,\n    Err(e) if e.to_string().starts_with(\"unexpected response shape\") => {\n        eprintln!(\"CLI/daemon protocol skew: {e:#}; update astrid CLI and daemon to matching versions\");\n        ExitCode::FAILURE\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Keep CLI and daemon on matching versions; AdminResponseBody variants must agree on both sides.","Match AdminResponseBody exhaustively and handle error bodies explicitly instead of relying on the `other` arm.","When adding a new response variant, update every command's match arm in the same change.","Log the full debug payload ({other:?}) to diagnose shape mismatches quickly."],"tags":["ipc","protocol","response-shape","cli","rust"],"backgroundTag":"unexpected-response-shape","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}