Hmbown/CodeWhale · error
percent-encoded Runtime cookie is a valid header
Error message
percent-encoded Runtime cookie is a valid header
What it means
Panic from `HeaderValue::from_str(&cookie)` while setting a Set-Cookie header in the runtime API bootstrap exchange. `from_str` fails only if the value contains non-visible-ASCII bytes; the code asserts the percent-encoded Runtime cookie is always header-safe.
Solutions
- Percent-encode the cookie value with `percent_encoding` covering all non-ASCII/control bytes before building the HeaderValue
- Validate the cookie with `HeaderValue::from_str(...).is_ok()` and fail loudly at generation time
- Log and reject tokens containing invalid characters at issuance instead of at header insertion
Example fix
// before
response.headers_mut().insert(
header::SET_COOKIE,
HeaderValue::from_str(&cookie).expect("percent-encoded Runtime cookie is a valid header"),
);
// after
let value = HeaderValue::from_str(&cookie)
.expect("percent-encoded Runtime cookie is a valid header; ensure token is fully percent-encoded");
response.headers_mut().insert(header::SET_COOKIE, value); Defensive patterns
Strategy: validation
Validate before calling
debug_assert!(HeaderValue::from_str(&cookie).is_ok(), "cookie contains non-header-safe bytes: {:?}", cookie); Type guard
fn is_header_safe(v: &str) -> bool { HeaderValue::from_str(v).is_ok() } Try / catch
let value = HeaderValue::from_str(&cookie).map_err(|e| anyhow::anyhow!("cookie not header-safe: {e}"))?; Prevention
- Percent-encode every cookie component with a strict ASCII encode set
- Round-trip test cookie generation with HeaderValue::from_str in CI
- Reject tokens containing control or non-ASCII characters at issuance
When it happens
Trigger: `exchange_bootstrap` producing a cookie containing raw non-ASCII, control characters, or newline bytes — i.e., the percent-encoding step failed to encode some character in the Runtime token.
Common situations: A token or session value containing characters outside the encoded alphabet after a change to cookie generation; non-UTF8-safe identifiers being embedded unencoded.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- generated mobile cookie is a valid header
- Codewhale chat request should succeed
- Codewhale messages request should succeed
- Codewhale responses request should succeed
- failed to build HTTP client
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/61488eed6d339401.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_api/web.rs:134
};
let session_token = match web.consume(&nonce, peer.ip()) {
Ok(token) => token,
Err(BootstrapError::NonLoopback) => {
return secured_text(StatusCode::FORBIDDEN, "bootstrap unavailable");
}
Err(BootstrapError::Invalid | BootstrapError::Expired) => {
return secured_text(StatusCode::UNAUTHORIZED, "bootstrap unavailable");
}
};
let cookie = web_session_cookie(&session_token);
let mut response = (StatusCode::SEE_OTHER, "").into_response();
response
.headers_mut()
.insert(header::LOCATION, HeaderValue::from_static("/"));
response.headers_mut().insert(
header::SET_COOKIE,
HeaderValue::from_str(&cookie).expect("percent-encoded Runtime cookie is a valid header"),
);
secure_headers(&mut response, "text/plain; charset=utf-8");
response
}
pub(super) async fn web_page(State(state): State<RuntimeApiState>) -> Response {
if state.web.is_none() {
return not_found();
}
secured_asset("text/html; charset=utf-8", WEB_HTML)
}
pub(super) async fn web_styles(State(state): State<RuntimeApiState>) -> Response {
if state.web.is_none() {
return not_found();
}
secured_asset("text/css; charset=utf-8", WEB_CSS)
}View on GitHub (pinned to 73e0f67d83)