can1357/oh-my-pi · error · LegacyDestinationError
the upload response did not contain a valid direct URL
Error message
the upload response did not contain a valid direct URL
What it means
This LegacyDestinationError is thrown by httpUrl() when a URL string extracted from an upload endpoint's HTTP response cannot be parsed by `new URL(raw)` (optionally resolved against the request's base endpoint URL). It indicates the remote service returned a malformed 'direct URL' field, and the underlying parse failure is attached as `cause`.
Source
Thrown at packages/coding-agent/src/blob-broker/uploaders-legacy.ts:100
}
}
return endpoint;
}
function sendSpaceEndpoint(config: DestinationRuntimeConfig): URL {
const endpoint = configuredEndpoint("sendspace", config);
if (endpoint.hostname.toLowerCase() === SENDSPACE_DEFAULT_HOST) {
throw new DestinationUnavailableError("sendspace", "the deprecated public discovery endpoint cannot be used");
}
return endpoint;
}
function httpUrl(destination: BlobDestinationId, raw: string, base?: URL): string {
let url: URL;
try {
url = base ? new URL(raw, base) : new URL(raw);
} catch (error) {
throw new LegacyDestinationError(destination, "the upload response did not contain a valid direct URL", error);
}
if (url.protocol !== "https:" && url.protocol !== "http:") {
throw new LegacyDestinationError(destination, "the upload response URL must use HTTP or HTTPS");
}
return url.href;
}
function objectValue(value: unknown): Readonly<Record<string, unknown>> {
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
return value as Readonly<Record<string, unknown>>;
}
function firstString(record: Readonly<Record<string, unknown>>, keys: readonly string[]): string | undefined {
for (const key of keys) {
const value = record[key];
if (typeof value === "string" && value.trim()) return value.trim();
}
return undefined;View on GitHub (pinned to 9690622007)
Solutions
- Inspect the raw HTTP response (log it or use a proxy) to see what the endpoint actually returned in the URL field
- Fix or replace the custom endpoint so it returns absolute http(s) URLs
- If the endpoint returns relative paths, front it with a proxy that rewrites them to absolute URLs
- Check the error's `cause` for the exact URL parse failure to identify the offending string
Defensive patterns
Strategy: try-catch
Type guard
function isAbsoluteHttpUrl(value: unknown): value is string {
if (typeof value !== "string") return false;
try {
const u = new URL(value);
return u.protocol === "https:" || u.protocol === "http:";
} catch {
return false;
}
} Try / catch
try {
const result = await uploader.upload(request);
} catch (err) {
if (err instanceof Error && err.message.includes("did not contain a valid direct URL")) {
console.error("cause:", err.cause); // inspect what the server returned
} else throw err;
} Prevention
- Test your replacement endpoint once with curl and inspect the response URL field
- Ensure the endpoint returns absolute http(s) URLs, never relative paths
- Log raw response bodies during integration of custom endpoints
- Validate third-party endpoint responses against the expected schema before rollout
When it happens
Trigger: An upload completes and the response JSON contains a `direct_url`/`directUrl`/`url`/`URL` field whose value is not a parseable URL — e.g. a relative path like '/files/abc.png' when no base resolution works, empty string that slipped past firstString, HTML snippet, or a truncated URL from a misbehaving proxy; called from directJsonUrl, url(), upload(), and discoverSendSpaceNode.
Common situations: Uploading to a self-hosted replacement endpoint that returns relative paths instead of absolute URLs; a reverse proxy injecting an error page whose extracted string is not a URL; service changed its response schema.
Related errors
- the upload response URL must use HTTP or HTTPS
- the upload endpoint returned invalid JSON
- the upload endpoint returned an invalid JSON object
- the upload response did not include a direct image URL
- Gemini Files API upload initialization request failed
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3d25c60c6e4735c3.
Report an issue: GitHub.