t8y2/dbx · critical

DBX_PUBLIC_BASE_PATH contains invalid characters

Error message

DBX_PUBLIC_BASE_PATH contains invalid characters

What it means

normalize_public_base_path sanitizes the DBX_PUBLIC_BASE_PATH environment variable into a leading-slash URL path prefix. It panics when the value contains ASCII control characters, whitespace, or the characters ';' or ',', which would corrupt routing/URL composition downstream. The crate refuses to start with an unsafe base path rather than silently normalizing it.

Source

Thrown at crates/dbx-web/src/main.rs:99

fn web_agent_dir(data_dir: &std::path::Path) -> std::path::PathBuf {
    web_agent_dir_from_env(data_dir, std::env::var("DBX_AGENT_DIR").ok())
}

fn web_agent_dir_from_env(data_dir: &std::path::Path, agent_dir: Option<String>) -> std::path::PathBuf {
    agent_dir.map(std::path::PathBuf::from).unwrap_or_else(|| data_dir.join("agents"))
}

fn normalize_public_base_path(value: Option<String>) -> String {
    let trimmed = value
        .unwrap_or_else(|| "/".to_string())
        .split(['?', '#'])
        .next()
        .unwrap_or("/")
        .trim()
        .trim_matches('/')
        .to_string();
    if trimmed.chars().any(|ch| ch.is_ascii_control() || ch.is_ascii_whitespace() || matches!(ch, ';' | ',')) {
        panic!("DBX_PUBLIC_BASE_PATH contains invalid characters");
    }
    if trimmed.is_empty() {
        "/".to_string()
    } else {
        format!("/{trimmed}")
    }
}

fn add_public_base_path_redirect<S>(app: Router<S>, public_base_path: &str) -> Router<S>
where
    S: Clone + Send + Sync + 'static,
{
    if public_base_path == "/" {
        return app;
    }

    // Derive the target from the configured base path so single- and multi-segment prefixes both work.
    let redirect_target = format!("{public_base_path}/");

View on GitHub (pinned to c0390bff16)

Solutions

  1. Remove spaces, control characters, semicolons, and commas from DBX_PUBLIC_BASE_PATH (e.g. use /api/v2 not /api, v2)
  2. Print the value with delimiters (printf '%q' "$DBX_PUBLIC_BASE_PATH") to reveal hidden whitespace/newlines before starting the app
  3. If the variable is unset/empty, the code already defaults to "/" — just unset it instead of passing a malformed value

Example fix

// before
DBX_PUBLIC_BASE_PATH="/api, v2"
// after
DBX_PUBLIC_BASE_PATH="/api/v2"
Defensive patterns

Strategy: validation

Validate before calling

fn valid_base_path(v: &str) -> bool {
    !v.chars().any(|c| c.is_ascii_control() || c.is_ascii_whitespace() || matches!(c, ';' | ','))
}
if let Ok(p) = std::env::var("DBX_PUBLIC_BASE_PATH") {
    assert!(valid_base_path(&p), "DBX_PUBLIC_BASE_PATH has invalid characters");
}

Type guard

fn is_clean_path(v: &str) -> bool {
    v.chars().all(|c| !c.is_ascii_control() && !c.is_ascii_whitespace() && !matches!(c, ';' | ','))
}

Prevention

When it happens

Trigger: Setting DBX_PUBLIC_BASE_PATH to a value containing spaces, tabs, newlines, control characters, semicolons, or commas (e.g. DBX_PUBLIC_BASE_PATH="/api, v2" or a path copied with a trailing newline from a shell/CI variable).

Common situations: Copy-pasting a path with hidden whitespace from docs or Slack, multi-value env vars built with commas/semicolons by mistake, or CI secret managers injecting values with trailing newlines.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/e65769571dd7f112. Report an issue: GitHub.