can1357/oh-my-pi · error · Error

Destination option ${optionName} must be an absolute HTTP UR

Error message

Destination option ${optionName} must be an absolute HTTP URL

What it means

Thrown by httpBase when a destination option that must be an absolute HTTP(S) URL (host base, apiUrl, publicBase, base) cannot be parsed by the URL constructor. The library builds API endpoints and public links from these bases, so they must be fully-qualified http:/https: URLs.

Source

Thrown at packages/coding-agent/src/blob-broker/uploaders-self-hosted.ts:134

function encodedPath(parts: readonly string[]): string {
	return parts.map(part => encodeURIComponent(part)).join("/");
}

function endpoint(base: string, ...parts: string[]): string {
	const url = new URL(base);
	url.pathname = `${url.pathname.replace(/\/+$/, "")}/${encodedPath(parts)}`;
	url.search = "";
	url.hash = "";
	return url.toString();
}

function httpBase(value: string, optionName: string): URL {
	let url: URL;
	try {
		url = new URL(value);
	} catch {
		throw new Error(`Destination option ${optionName} must be an absolute HTTP URL`);
	}
	if (url.protocol !== "http:" && url.protocol !== "https:") {
		throw new Error(`Destination option ${optionName} must use http or https`);
	}
	return url;
}

function publicUrl(baseValue: string, directory: string | undefined, filename: string): string {
	const url = httpBase(baseValue, "publicBaseUrl");
	const relative = encodedPath([...pathParts(directory), filename]);
	url.pathname = `${url.pathname.replace(/\/+$/, "")}/${relative}`;
	url.hash = "";
	return url.toString();
}

function basicAuthorization(username: string, password: string): string {
	return `Basic ${Buffer.from(`${username}:${password}`, "utf8").toString("base64")}`;
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Add the scheme and both slashes: change 'mycloud.example.com' to 'https://mycloud.example.com'
  2. Fix common typos: 'https:/host' -> 'https://host', remove trailing spaces or wrapping quotes
  3. Use http:// only for local testing (e.g. http://localhost:8080); production should use https://
  4. Pre-validate with `new URL(value)` and check protocol is http:/https: before saving the destination config

Example fix

// before
{ "apiUrl": "mycloud.example.com/ocs/v1.php" }
// after
{ "apiUrl": "https://mycloud.example.com/ocs/v1.php" }
Defensive patterns

Strategy: validation

Validate before calling

function assertHttpBase(value: string, optionName: string): void {
  let u: URL;
  try { u = new URL(value); } catch { throw new Error(`Destination option ${optionName} must be an absolute HTTP URL, got ${JSON.stringify(value)}`); }
  if (u.protocol !== "http:" && u.protocol !== "https:") throw new Error(`Destination option ${optionName} must use http or https`);
}
assertHttpBase(destConfig.apiUrl, "apiUrl");

Type guard

function isHttpUrl(value: string): boolean {
  try { const u = new URL(value); return u.protocol === "http:" || u.protocol === "https:"; } catch { return false; }
}

Try / catch

try {
  const uploader = createOwnCloudUploader(dest);
} catch (err) {
  const m = (err as Error).message.match(/Destination option (\S+) must be an absolute HTTP URL/);
  if (m) throw new Error(`Fix '${m[1]}' in your destination config — it must include a scheme, e.g. https://host`);
  throw err;
}

Prevention

When it happens

Trigger: Configuring an option like 'https:/host' (single slash), 'mycloud.example.com' (no scheme), 'ftp://host', 'localhost:8080' (parsed as scheme 'localhost:'), or an empty/typo'd string wherever httpBase validates it (url, createFtpUploader, createSharedFolderUploader, host, apiUrl, base).

Common situations: Omitting the scheme (bare hostname), using a protocol-relative '//host' value, typos like 'http//' or 'https:/', paste errors with surrounding quotes/spaces, or pointing an HTTP-based uploader at an ftp/s3 scheme URL.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/75bb61b36c7d4903. Report an issue: GitHub.