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
- Remove spaces, control characters, semicolons, and commas from DBX_PUBLIC_BASE_PATH (e.g. use /api/v2 not /api, v2)
- Print the value with delimiters (printf '%q' "$DBX_PUBLIC_BASE_PATH") to reveal hidden whitespace/newlines before starting the app
- 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
- Quote env values in shell scripts to avoid accidental whitespace
- Lint CI/secret-manager outputs for trailing newlines
- Keep base paths to [A-Za-z0-9/_-] only
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- error while building tauri application: {error}
- Invalid DBX Web MCP configuration
- Invalid ${name}: ${error.message}
- DBX Pi MCP bridge configuration is incomplete
- start %s: %w
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/e65769571dd7f112.
Report an issue: GitHub.