can1357/oh-my-pi · error · Error
collab.webUrl must start with http:// or https://
Error message
collab.webUrl must start with http:// or https://
What it means
normalizeCollabWebBaseUrl throws this when the explicitly configured webUrl cannot be parsed as a URL at all, or when its protocol is neither http: nor https:. The message is the same in both cases because a URL like 'collab.example.com' or 'wss://...' would fail here — the web base must be an HTTP(S) URL that browsers can open.
Source
Thrown at packages/coding-agent/src/collab/protocol.ts:221
: normalized.origin;
return `${compact}/r/${roomId}.${keyText}`;
}
function normalizeCollabWebBaseUrl(relayUrl: string, webUrl?: string): string {
const explicitWebUrl = webUrl?.trim();
if (!explicitWebUrl) {
const normalized = normalizeRelayOrigin(relayUrl);
if ("error" in normalized) throw new Error(normalized.error);
return normalized.origin.startsWith("wss://")
? `https://${normalized.origin.slice("wss://".length)}`
: `http://${normalized.origin.slice("ws://".length)}`;
}
let url: URL;
try {
url = new URL(explicitWebUrl);
} catch {
throw new Error("collab.webUrl must start with http:// or https://");
}
if (url.protocol !== "http:" && url.protocol !== "https:") {
throw new Error("collab.webUrl must start with http:// or https://");
}
if (url.protocol === "http:" && !isLocalHostname(url.hostname)) {
throw new Error("collab.webUrl must use https:// unless it targets localhost");
}
if (url.search || url.hash) {
throw new Error("collab.webUrl must not include a query string or fragment");
}
const path = url.pathname.replace(/\/+$/, "");
return `${url.origin}${path}`;
}
/**
* Render the browser deep link. The browser UI may be hosted separately from
* the relay; the fragment always carries the relay-specific collab link, so
* room secrets stay out of HTTP path and query bytes.View on GitHub (pinned to 9690622007)
Solutions
- Set webUrl to a full URL with http:// or https:// scheme, e.g. https://collab.example.com.
- Do not reuse the relay's ws:// or wss:// URL as webUrl; derive the https address of the web UI instead.
- Trim the value and strip quotes before saving; verify with new URL(webUrl) in a quick script.
- Omit webUrl entirely to derive it from the relay origin.
Example fix
// before webUrl: "collab.example.com" // after webUrl: "https://collab.example.com"
Defensive patterns
Strategy: validation
Validate before calling
function webUrlOk(s: string): boolean {
try { const u = new URL(s.trim()); return u.protocol === "http:" || u.protocol === "https:"; }
catch { return false; }
}
if (!webUrlOk(webUrl)) throw new Error("webUrl must be an absolute http(s) URL");
formatCollabWebLink(relayUrl, roomId, key, token, webUrl.trim()); Try / catch
try {
const webLink = formatCollabWebLink(relayUrl, roomId, key, token, webUrl);
} catch (err) {
ui.showError(`Invalid collab.webUrl: ${(err as Error).message}`);
} Prevention
- Always include the http:// or https:// scheme in collab.webUrl.
- Never reuse the relay's ws:// URL as the web base.
- Trim config values and strip stray quotes before use.
When it happens
Trigger: Calling formatCollabWebLink with webUrl set to: a scheme-less host ('collab.example.com'), a ws/wss URL, an ftp:// URL, or any string new URL() rejects (spaces, stray characters, empty after trim).
Common situations: Config collab.webUrl copied from the relay's wss:// address instead of the web UI's https:// address; webUrl set to a bare hostname; trailing whitespace or quotes left in a config value making new URL throw.
Related errors
- error
- error
- resultBaseUrl is not a valid URL
- Destination option ${optionName} must use http or https
- collab.webUrl must use https:// unless it targets localhost
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/148ff55405c07732.
Report an issue: GitHub.