Hmbown/CodeWhale · error
generated mobile fragment is a valid header
Error message
generated mobile fragment is a valid header
What it means
The mobile login handler builds a redirect Location header from a session fragment and calls `HeaderValue::from_str(...).expect(...)`. `from_str` only fails for bytes outside visible HTTP header range (control chars), so this expect asserts the internally generated URL never contains such characters. A panic means the location string (base URL/path/fragment construction) produced an invalid header value.
Solutions
- Audit where `location` is built and percent-encode or strip non-visible characters before insertion
- Validate the configured base URL at startup (reject CRLF/control chars)
- Replace expect with graceful handling that returns a 500 instead of panicking the handler
- Add a unit test that the fragment builder output passes HeaderValue::from_str
Example fix
// before
HeaderValue::from_str(&location).expect("generated mobile fragment is a valid header")
// after
HeaderValue::from_str(&location).unwrap_or_else(|_| {
tracing::error!("invalid mobile location header");
HeaderValue::from_static("/")
}) Defensive patterns
Strategy: validation
Validate before calling
// rust
fn is_valid_header_value(s: &str) -> bool {
s.bytes().all(|b| (32..=126).contains(&b) || b == b'\t')
}
// call before building the response:
assert!(is_valid_header_value(&location)); Type guard
// rust
fn valid_header(s: &str) -> Option<HeaderValue> {
HeaderValue::from_str(s).ok()
} Try / catch
// rust
match HeaderValue::from_str(&location) {
Ok(v) => response.headers_mut().insert(header::LOCATION, v),
Err(e) => { tracing::error!("bad location header: {e}"); return StatusCode::INTERNAL_SERVER_ERROR.into_response(); }
} Prevention
- Percent-encode any user input interpolated into redirect URLs
- Validate configured base URLs reject control characters at startup
- Unit-test header generation with CRLF inputs
When it happens
Trigger: The generated mobile fragment URL contains control characters or non-visible bytes — e.g. a configured external base URL with a newline/CR, unvalidated query parameters interpolated into the fragment, or corrupted session data feeding the location.
Common situations: Misconfigured PUBLIC/base URL containing whitespace or CRLF, user-controlled fragments concatenated into the redirect target, template bugs introducing `%0A`/raw newlines.
Related errors
- generated mobile cookie is a valid header
- failed to build HTTP client
- ApplyPatchPreflight should serialize
- bing result regex pattern is valid
- bing snippet regex pattern is valid
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/0f56fcd93ff14f84.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_api.rs:1402
let session = match mobile_state.consume_bootstrap(&nonce, peer.ip()) {
Ok(session) => session,
Err(mobile::BootstrapError::NonLoopback) => {
return secured_mobile_text(StatusCode::FORBIDDEN, "bootstrap unavailable");
}
Err(mobile::BootstrapError::Invalid | mobile::BootstrapError::Expired) => {
return secured_mobile_text(StatusCode::UNAUTHORIZED, "bootstrap unavailable");
}
};
let location = format!(
"/mobile#request_proof={}&stream_ticket={}",
session.request_proof, session.stream_ticket
);
let cookie = mobile::mobile_session_cookie(&session.session_cookie);
let mut response = (StatusCode::SEE_OTHER, "").into_response();
response.headers_mut().insert(
header::LOCATION,
HeaderValue::from_str(&location).expect("generated mobile fragment is a valid header"),
);
response.headers_mut().insert(
header::SET_COOKIE,
HeaderValue::from_str(&cookie).expect("generated mobile cookie is a valid header"),
);
secure_mobile_response(&mut response);
response
}
async fn exchange_mobile_session(State(state): State<RuntimeApiState>, req: Request) -> Response {
let Some(mobile_state) = state.mobile.as_ref() else {
return mobile_not_found();
};
let Some(expected) = state.runtime_token.as_deref() else {
return mobile_not_found();
};
if !auth::request_has_header_runtime_token(&req, expected) {
return mobile_unauthorized();View on GitHub (pinned to 433685b202)