Hmbown/CodeWhale · error
outbound origin must not embed credentials
Error message
outbound origin must not embed credentials
What it means
The origin validator rejects URLs carrying userinfo (user:pass@host) so credentials never ride along inside the origin itself. Credentials must be supplied out of band (headers/env), not embedded in the URL.
Solutions
- Remove the user:password@ portion from the URL and pass the credential via the appropriate header or env var.
- Check env var contents: strip any '@'-style credential suffix before setting DAYTONA_API_URL.
- Move secrets out of config files into the credential store / environment.
Example fix
// before export DAYTONA_API_URL=https://user:token@api.example.com // after export DAYTONA_API_URL=https://api.example.com export DAYTONA_API_KEY=token
Defensive patterns
Strategy: validation
Validate before calling
fn has_userinfo(raw: &str) -> bool {
reqwest::Url::parse(raw.trim()).map(|u| !u.username().is_empty() || u.password().is_some()).unwrap_or(false)
} Try / catch
if has_userinfo(raw) {
eprintln!("strip user:pass@ from the origin; pass credentials via headers/env");
} Prevention
- Never embed credentials in URLs; use env vars or a credential store.
- Sanitize copied URLs of '@' userinfo before saving config.
- Audit config files for basic-auth-style URLs.
When it happens
Trigger: Configuring an origin like https://user:token@api.example.com or https://admin@host/ as the remote endpoint or toolbox URL.
Common situations: Copying a URL that worked in a browser/curl with embedded basic-auth; legacy tooling that expected credentials in the URL; secrets committed into config files.
Related errors
- outbound origin is empty or oversized
- reviewed plugin MCP endpoint has an unsafe origin
- api_key cannot be empty string
- --base-url must use http or https
- browser URL cannot be empty
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/61c7156428685877.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/cloud_dispatch.rs:1267
/// - explicit loopback hosts (`localhost`, `127.0.0.1`, `::1`) are allowed
/// only in debug builds, as the escape hatch for local smoke tests against
/// a self-hosted sandbox service; release builds reject them outright.
/// - the host must not be a private / link-local / reserved / multicast
/// address or a `.local` / `.internal` name, and no userinfo may ride
/// along.
///
/// DNS-resolved rebinding is out of scope and documented as such.
pub fn validate_outbound_origin(raw: &str) -> Result<reqwest::Url> {
let trimmed = raw.trim();
if trimmed.is_empty() || trimmed.len() > MAX_REMOTE_BYTES {
bail!("outbound origin is empty or oversized");
}
let url = reqwest::Url::parse(trimmed).context("outbound origin is not a valid URL")?;
if !matches!(url.scheme(), "http" | "https") {
bail!("outbound origin must be http or https");
}
if !url.username().is_empty() || url.password().is_some() {
bail!("outbound origin must not embed credentials");
}
let host = url
.host_str()
.context("outbound origin has no host")?
.trim_end_matches('.')
.to_ascii_lowercase();
// `Url::host_str` keeps IPv6 brackets; strip them for the checks below.
let host = host
.strip_prefix('[')
.and_then(|inner| inner.strip_suffix(']'))
.map(str::to_string)
.unwrap_or(host);
let loopback_name = host == "localhost" || host == "127.0.0.1" || host == "::1";
if loopback_name {
if cfg!(debug_assertions) {
return Ok(url);
}
bail!("loopback origins are not allowed in release builds");View on GitHub (pinned to 73e0f67d83)