can1357/oh-my-pi · error · LegacyDestinationError
the configured endpoint is not a valid URL
Error message
the configured endpoint is not a valid URL
What it means
This LegacyDestinationError is thrown when the user-configured `endpoint` option for a legacy blob destination (puush, mediafire, localhostr, lambda, lobfile, transfer-sh, sendspace, etc.) cannot be parsed by the URL constructor. The library requires a custom replacement endpoint because the original public services are defunct, and it validates the value with `new URL(raw)` before any network I/O. It wraps the underlying parse error as `cause`.
Source
Thrown at packages/coding-agent/src/blob-broker/uploaders-legacy.ts:70
readonly extraInfo: string;
}
function failure(destination: BlobDestinationId, error: unknown): Error {
if (error instanceof DestinationUnavailableError || error instanceof LegacyDestinationError) return error;
const message = error instanceof Error ? error.message : String(error);
return new LegacyDestinationError(destination, message, error);
}
function configuredEndpoint(destination: BlobDestinationId, config: DestinationRuntimeConfig): URL {
const raw = optionString(config, "endpoint")?.trim();
if (!raw) {
throw new DestinationUnavailableError(destination, "a user-supplied replacement endpoint is required");
}
let endpoint: URL;
try {
endpoint = new URL(raw);
} catch (error) {
throw new LegacyDestinationError(destination, "the configured endpoint is not a valid URL", error);
}
if (endpoint.protocol !== "https:" && endpoint.protocol !== "http:") {
throw new LegacyDestinationError(destination, "the configured endpoint must use HTTP or HTTPS");
}
const hostname = endpoint.hostname.toLowerCase();
const blocked = BLOCKED_CUSTOM_HOSTS[destination];
if (blocked) {
for (const domain of blocked) {
if (hostname === domain || hostname.endsWith(`.${domain}`)) {
throw new DestinationUnavailableError(destination, "the defunct public endpoint cannot be used");
}
}
}
return endpoint;
}
function sendSpaceEndpoint(config: DestinationRuntimeConfig): URL {
const endpoint = configuredEndpoint("sendspace", config);View on GitHub (pinned to 9690622007)
Solutions
- Prefix the endpoint with an explicit scheme, e.g. change 'files.example.com/upload' to 'https://files.example.com/upload'
- Trim quotes, whitespace, and template remnants from the configured endpoint value
- Validate the string with `new URL(value)` before saving it to configuration
- Check the wrapped `cause` property of the error for the exact WHATWG URL parse failure
Example fix
// before endpoint: files.example.com/upload // after endpoint: https://files.example.com/upload
Defensive patterns
Strategy: validation
Validate before calling
function isValidHttpUrl(value) {
try {
const u = new URL(String(value).trim());
return u.protocol === "https:" || u.protocol === "http:";
} catch {
return false;
}
}
if (!isValidHttpUrl(config.endpoint)) throw new Error("endpoint must be an absolute http(s) URL"); Type guard
function isHttpUrl(value: unknown): value is URL {
try {
const u = new URL(String(value));
return u.protocol === "https:" || u.protocol === "http:";
} catch {
return false;
}
} Try / catch
try {
await uploader.upload(request);
} catch (err) {
if (err instanceof Error && err.message.includes("not a valid URL")) {
// fix config.endpoint: add scheme, trim junk
} else throw err;
} Prevention
- Always include an explicit https:// scheme in endpoint config values
- Trim surrounding whitespace and quotes before storing the endpoint
- Validate the endpoint with new URL() at config-load time, not upload time
- Keep endpoints in typed config with a parse-time assertion
When it happens
Trigger: Calling an uploader that resolves its endpoint via configuredEndpoint() (e.g. createLegacyUploader -> endpoint) with config.endpoint set to a string that fails `new URL()`: a bare hostname like 'example.com/upload' without a scheme, an empty-after-trim value is handled separately, typos like 'https//...', or values with spaces/invalid characters.
Common situations: Users copy a replacement endpoint from documentation and omit the `https://` scheme; environment variables or YAML config with trailing whitespace/quotes left in the value; template expansion producing 'undefined' or placeholder text in the endpoint string.
Related errors
- the configured endpoint must use HTTP or HTTPS
- the defunct public endpoint cannot be used
- the upload response did not contain a valid direct URL
- credentials ${usernameKey} and ${passwordKey} must be config
- No model configured
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3ebb89b3d313e8a6.
Report an issue: GitHub.