{"record":{"id":"4610f70d6a1e89c3","repo":"different-ai/openwork","slug":"den-api-public-url-must-be-an-absolute-http-or-htt","errorCode":null,"errorMessage":"DEN_API_PUBLIC_URL must be an absolute http or https URL.","messagePattern":"DEN_API_PUBLIC_URL must be an absolute http or https URL\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-api/src/request-url.ts","lineNumber":96,"sourceCode":"function isLocalPublicApiHost(hostname: string): boolean {\n  const normalized = hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\")\n  return normalized === \"localhost\"\n    || normalized.endsWith(\".localhost\")\n    || normalized === \"127.0.0.1\"\n    || normalized === \"::1\"\n}\n\nexport function normalizeConfiguredPublicApiBaseUrl(\n  value: string | undefined,\n  options: { allowInsecureHttp: boolean },\n): string | undefined {\n  const configured = value?.trim()\n  if (!configured) return undefined\n\n  let url: URL\n  try {\n    url = new URL(configured)\n  } catch {\n    throw new Error(\"DEN_API_PUBLIC_URL must be an absolute http or https URL.\")\n  }\n\n  if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n    throw new Error(\"DEN_API_PUBLIC_URL must be an absolute http or https URL.\")\n  }\n  if (url.username || url.password || url.search || url.hash) {\n    throw new Error(\"DEN_API_PUBLIC_URL cannot contain credentials, a query string, or a fragment.\")\n  }\n  if (url.protocol !== \"https:\" && !options.allowInsecureHttp && !isLocalPublicApiHost(url.hostname)) {\n    throw new Error(\"DEN_API_PUBLIC_URL must use HTTPS outside development and localhost.\")\n  }\n\n  const pathname = url.pathname.replace(/\\/+$/, \"\")\n  return `${url.origin}${pathname === \"/\" ? \"\" : pathname}`\n}\n","sourceCodeStart":78,"sourceCodeEnd":113,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/request-url.ts#L78-L113","documentation":"This error is thrown by normalizeConfiguredPublicApiBaseUrl when the DEN_API_PUBLIC_URL environment variable is set but cannot be parsed as an absolute URL by the URL constructor — e.g. it lacks a scheme or is malformed. The variable defines the externally visible base URL for building public API links, so it must be a valid absolute http/https URL.","triggerScenarios":"apiPublicUrl reads DEN_API_PUBLIC_URL with a value like \"api.example.com\", \"localhost:3000\", \"//host\", or containing spaces; new URL(configured) throws and this Error propagates at startup or first URL build.","commonSituations":"Deploy config omits the https:// scheme; a trailing quote/space leaked into the env var; a relative path was supplied; the value was set in one environment but pasted incorrectly in another (Docker env, Terraform, Railway/Render dashboard).","solutions":["Set DEN_API_PUBLIC_URL to a fully qualified URL including scheme, e.g. https://api.example.com.","Check the deployment environment/secret store for stray whitespace or quotes around the value and trim them.","If the variable is optional in your setup, unset it entirely instead of leaving an invalid partial value.","Add a startup env validation step (e.g. Zod .url()) so misconfiguration fails fast with a clear message."],"exampleFix":"// before\nDEN_API_PUBLIC_URL=api.openworklabs.com\n// after\nDEN_API_PUBLIC_URL=https://api.openworklabs.com","handlingStrategy":"validation","validationCode":"const v = process.env.DEN_API_PUBLIC_URL?.trim()\nif (v) {\n  let u: URL\n  try { u = new URL(v) } catch { throw new Error(\"DEN_API_PUBLIC_URL must be an absolute http or https URL\") }\n  if (u.protocol !== \"http:\" && u.protocol !== \"https:\") throw new Error(\"DEN_API_PUBLIC_URL must be an absolute http or https URL\")\n}","typeGuard":"function isAbsoluteHttpUrl(value: string | undefined): value is string {\n  if (!value) return false\n  try { const u = new URL(value); return u.protocol === \"http:\" || u.protocol === \"https:\" } catch { return false }\n}","tryCatchPattern":"try {\n  const baseUrl = apiPublicUrl(env)\n} catch (e) {\n  if (e.message.includes(\"DEN_API_PUBLIC_URL\")) {\n    throw new Error(`Startup config invalid: set DEN_API_PUBLIC_URL to e.g. https://api.example.com (${e.message})`)\n  }\n  throw e\n}","preventionTips":["Always include the scheme (https://) in env-provided URLs","Validate env vars at startup with Zod (.url()) so failures are immediate and clear","Trim and strip quotes from env values in deploy templates","Document the expected format next to the variable in deployment configs"],"tags":["configuration","env","url","startup"],"backgroundTag":"invalid-env-var","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}