Hmbown/CodeWhale · critical · anyhow::Error
app-server auth token cannot be empty
Error message
app-server auth token cannot be empty
What it means
The app-server resolves its authentication token from AppServerOptions before binding. If an auth_token was explicitly configured but consists only of whitespace after trimming, resolve_auth_token bails with this error. An explicitly-set-but-empty token is treated as a misconfiguration that must fail loudly rather than silently degrading to no-auth or a generated token.
Solutions
- Provide a real non-empty token in AppServerOptions.auth_token
- Fix the environment variable or config file so it contains the actual secret
- If you truly want no authentication, explicitly set insecure_no_auth (loopback binds only) instead of an empty token
- Unset/omit the auth_token field entirely so the server's default token resolution applies
Example fix
// before
let opts = AppServerOptions { auth_token: Some("".into()), .. };
// after
let opts = AppServerOptions { auth_token: Some(real_token), .. }; Defensive patterns
Strategy: validation
Validate before calling
let auth_token = env::var("APP_SERVER_AUTH_TOKEN").unwrap_or_default();
if !auth_token.trim().is_empty() {
opts.auth_token = Some(auth_token);
} // else leave unset so the server's default resolution applies Type guard
fn has_token(t: &Option<String>) -> bool { t.as_deref().map_or(false, |s| !s.trim().is_empty()) } Try / catch
match app_server::run(opts) {
Err(e) if e.to_string().contains("auth token cannot be empty") => {
eprintln!("auth_token configured but blank; fix APP_SERVER_AUTH_TOKEN or set insecure_no_auth");
std::process::exit(2);
}
r => r,
} Prevention
- Trim and validate tokens at config-load time, not at server start
- Never write `auth_token = ""` in config templates; omit the key instead
- Verify secret injection in CI actually resolved to a non-empty value
- Use insecure_no_auth explicitly (loopback only) rather than an empty token for local testing
When it happens
Trigger: Constructing AppServerOptions with auth_token: Some("") or Some(" ") and starting the server; loading the token from a config file or environment variable that is present but blank.
Common situations: An env var like APP_SERVER_AUTH_TOKEN set to an empty string in a deployment manifest; a config template with `auth_token = ""` left unfilled; CI injecting a secret that resolved to empty.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- agent profile provider cannot be empty
- agent profile provider must be a simple provider id
- Antigravity cloud-code HTTP
- Antigravity cloud-code request is missing a model id
- client with secret sentinels
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/c048fda5fe175d9c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/app-server/src/lib.rs:876
Ok(AppState {
config_path,
config: Arc::new(RwLock::new(config)),
runtime: Arc::new(RwLock::new(runtime)),
registry,
auth_token,
runtime_bridge: Arc::new(Mutex::new(None)),
runtime_thread_map: Arc::new(Mutex::new(HashMap::new())),
stdio_thread_hints: Arc::new(Mutex::new(HashMap::new())),
in_flight_turns: Arc::new(Mutex::new(HashMap::new())),
})
}
fn resolve_auth_token(options: &AppServerOptions) -> Result<Option<String>> {
let configured = options.auth_token.as_ref().map(|token| token.trim());
if let Some(token) = configured
&& token.is_empty()
{
bail!("app-server auth token cannot be empty");
}
let has_explicit_token = configured.is_some();
if options.insecure_no_auth {
if !options.listen.ip().is_loopback() {
bail!("refusing unauthenticated app-server bind on non-loopback address");
}
eprintln!("warning: app-server HTTP auth disabled by --insecure-no-auth");
return Ok(None);
}
if !has_explicit_token && !options.listen.ip().is_loopback() {
bail!(
"refusing non-loopback app-server bind without explicit auth token; pass --auth-token or set CODEWHALE_APP_SERVER_TOKEN"
);
}
let token = configuredView on GitHub (pinned to 73e0f67d83)