pbakaus/impeccable · error
Reply failed: Unauthorized
Error message
Reply failed: Unauthorized
What it means
A 401 response on the reply POST is mapped to this hardcoded message. The live server rejected the authentication token that live-poll sent, so the reply was not accepted. Matching the JS implementation, the command prints `Reply failed: Unauthorized` and exits 1.
Source
Thrown at crates/live/src/live_poll.rs:731
Ok(Some(r)) => r,
Ok(None) => return 0,
Err(msg) => {
io.err(&format!("{}\n", msg));
return 1;
}
};
return match post_reply(&base, &token, &reply) {
Ok(()) => 0,
Err(PollError::ConnRefused) => {
io.err(&format!(
"Live server not running. Start one with: {}\n",
script_cmd(&env, &cwd, "live")
));
1
}
Err(PollError::Auth) => {
// JS: a 401 on the reply POST is a non-ok response -> "Reply failed: <body.error>"
io.err("Reply failed: Unauthorized\n");
1
}
Err(PollError::AckTimeout(m)) | Err(PollError::Other(m)) => {
io.err(&format!("Reply failed: {}\n", m));
1
}
};
}
let stream_mode = argv.iter().any(|a| a == "--stream");
let types_arg = argv
.iter()
.find(|a| a.starts_with("--types="))
.map(|a| a["--types=".len()..].to_string());
let types = normalize_poll_types(types_arg.as_deref());
let ack_timeout_ms = arg_value_int(&argv, "--ack-timeout=", 600_000);
if stream_mode {View on GitHub (pinned to 2bc2879276)
Solutions
- Stop and restart the live server so the info file's token matches the running process, then retry the reply.
- Delete the stale server info file and start a fresh `live` session.
- Ensure only one live server session exists for the workspace so poll reads the correct token.
Example fix
// before $ impeccable live-poll --reply --reply-text hi Reply failed: Unauthorized // after $ <self_cmd> live-server stop $ ./scripts/impeccable live & $ impeccable live-poll --reply --reply-text hi
Defensive patterns
Strategy: fallback
Validate before calling
// shell: if the info file predates the running server process, restart to refresh the token
pid=$(jq -r .pid .impeccable/live-server.json 2>/dev/null)
kill -0 "$pid" 2>/dev/null || { <self_cmd> live-server stop; ./scripts/impeccable live; } Try / catch
// on Unauthorized, restart the server and re-read the token before retrying
try {
postReply(text);
} catch (e) {
if (/Unauthorized/.test(String(e.stderr))) {
execSync('<self_cmd> live-server stop && ./scripts/impeccable live');
postReply(text); // retry with fresh token from the new info file
} else throw e;
} Prevention
- Never copy or hand-edit the server info file; always derive the token from a live session.
- Ensure only one live server runs per workspace.
- Restart the server whenever its process is recycled so tokens stay in sync.
When it happens
Trigger: `impeccable live-poll --reply` where `post_reply` returns `PollError::Auth` — the token read from the server info file does not match what the live server expects (401 from the endpoint).
Common situations: The live server was restarted and generated a new token while an old info file was reused; two live sessions in the same workspace and polling the wrong one; manually editing or copying session files between directories.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Status failed: ${res.status} ${res.statusText}
- Poll failed: ${res.status} ${res.statusText}
- Reply failed: {}
- Live browser script part missing: ${part.name} (${part.path}
- Not found
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/825233c42d867aa8.
Report an issue: GitHub.