different-ai/openwork · error
DEN_API_PUBLIC_URL cannot contain credentials, a query strin
Error message
DEN_API_PUBLIC_URL cannot contain credentials, a query string, or a fragment.
What it means
This error is thrown when DEN_API_PUBLIC_URL parses as an absolute http/https URL but also embeds userinfo (username/password), a query string, or a fragment. Such components make the value unsuitable as a clean base URL used to construct public API links, so normalizeConfiguredPublicApiBaseUrl rejects it.
Source
Thrown at ee/apps/den-api/src/request-url.ts:104
export function normalizeConfiguredPublicApiBaseUrl(
value: string | undefined,
options: { allowInsecureHttp: boolean },
): string | undefined {
const configured = value?.trim()
if (!configured) return undefined
let url: URL
try {
url = new URL(configured)
} catch {
throw new Error("DEN_API_PUBLIC_URL must be an absolute http or https URL.")
}
if (url.protocol !== "http:" && url.protocol !== "https:") {
throw new Error("DEN_API_PUBLIC_URL must be an absolute http or https URL.")
}
if (url.username || url.password || url.search || url.hash) {
throw new Error("DEN_API_PUBLIC_URL cannot contain credentials, a query string, or a fragment.")
}
if (url.protocol !== "https:" && !options.allowInsecureHttp && !isLocalPublicApiHost(url.hostname)) {
throw new Error("DEN_API_PUBLIC_URL must use HTTPS outside development and localhost.")
}
const pathname = url.pathname.replace(/\/+$/, "")
return `${url.origin}${pathname === "/" ? "" : pathname}`
}
View on GitHub (pinned to 2b7df46e8a)
Solutions
- Strip the query string, fragment, and any user:pass@ prefix, leaving only scheme+host+optional base path.
- Move credentials out of the URL into dedicated env vars/secrets if authentication is needed.
- Re-test with new URL(value) and assert username/password/search/hash are all empty before deploying.
- If a base path is required (e.g. /api), keep the path — only query/fragment/userinfo are rejected.
Example fix
// before DEN_API_PUBLIC_URL=https://admin:s3cret@api.example.com/mcp?region=us#hooks // after DEN_API_PUBLIC_URL=https://api.example.com/mcp
Defensive patterns
Strategy: validation
Validate before calling
const u = new URL(process.env.DEN_API_PUBLIC_URL ?? "")
if (u.username || u.password || u.search || u.hash) {
throw new Error("DEN_API_PUBLIC_URL must not contain credentials, query string, or fragment")
} Type guard
function isCleanBaseUrl(value: string | undefined): value is string {
try {
const u = new URL(value ?? "")
return (u.protocol === "http:" || u.protocol === "https:") && !u.username && !u.password && !u.search && !u.hash
} catch { return false }
} Try / catch
try {
const baseUrl = apiPublicUrl(env)
} catch (e) {
if (e.message.includes("credentials, a query string, or a fragment")) {
console.error("Strip user:pass@, ?query, and #fragment from DEN_API_PUBLIC_URL")
process.exit(1)
}
throw e
} Prevention
- Copy base URLs from config, never from the browser address bar
- Keep credentials in dedicated secret env vars, not in URLs
- Assert URL components are empty in a pre-deploy validation script
- If a base path is needed, keep only the path (e.g. /api) — no query/fragment
When it happens
Trigger: DEN_API_PUBLIC_URL values like "https://user:pass@api.example.com", "https://api.example.com/?env=prod", or "https://api.example.com/#main" — any non-empty url.username, url.password, url.search, or url.hash.
Common situations: Pasting a full URL copied from a browser address bar including #section or ?token=...; embedding basic-auth credentials in the URL instead of a secret; template tooling appending query parameters for tracking.
Related errors
- DEN_API_PUBLIC_URL must be an absolute http or https URL.
- DEN_API_PUBLIC_URL must use HTTPS outside development and lo
- An enterprise MCP server URL must use HTTP or HTTPS.
- An enterprise MCP server URL cannot contain a fragment.
- An enterprise MCP server URL must use HTTP or HTTPS.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/67439779c896d63a.
Report an issue: GitHub.