can1357/oh-my-pi · error · LegacyDestinationError
the replacement endpoint did not return a direct image URL
Error message
the replacement endpoint did not return a direct image URL
What it means
Thrown by the replacement uploader when the endpoint's JSON response contains no usable direct image URL: none of the known URL fields were present, and id/name/publicBaseUrl were insufficient (or absent) to construct one. The library refuses to publish without a resolvable public URL.
Source
Thrown at packages/coding-agent/src/blob-broker/uploaders-legacy.ts:306
try {
const response = await fetchFor(config)(endpoint, {
method: "POST",
headers,
body: multipartFile(request),
});
await expectOk(response, destination);
const data = await jsonObject(destination, response);
let raw = firstString(data, ["direct_url", "directUrl", "url"]);
if (!raw) {
const id = firstString(data, ["id"]);
const name = firstString(data, ["name"]);
const publicBase = optionString(config, "publicBaseUrl");
if (id && name && publicBase) {
raw = `${publicBase.replace(/\/$/, "")}/file/${encodeURIComponent(id)}/${encodeURIComponent(name)}`;
}
}
if (!raw)
throw new LegacyDestinationError(
destination,
"the replacement endpoint did not return a direct image URL",
);
const remoteId = firstString(data, ["id"]);
return publication(
destination,
request,
httpUrl(destination, raw, endpoint),
remoteId ? { remoteId } : undefined,
);
} catch (error) {
throw failure(destination, error);
}
},
};
}
function createLambdaUploader(config: DestinationRuntimeConfig, endpoint: URL): BlobUploader {View on GitHub (pinned to 9690622007)
Solutions
- Inspect the response JSON (available via the wrapped cause/failure) and compare against the expected fields
- Set the publicBaseUrl option if the endpoint returns only id/name so the library can build /file/<id>/<name> URLs
- Update or replace the endpoint with one that returns a direct_url/url field
- Check whether the upstream service changed its API version and adjust configuration
Example fix
// before: endpoint returns only ids, no publicBaseUrl configured
config: { endpoint: "https://host.example/api/upload", apiKey }
// after: supply publicBaseUrl so id+name can form a URL
config: { endpoint: "https://host.example/api/upload", apiKey, publicBaseUrl: "https://host.example" } Defensive patterns
Strategy: validation
Validate before calling
// ensure publicBaseUrl is set when your endpoint returns ids instead of direct URLs
const cfg = { endpoint, apiKey, publicBaseUrl: "https://host.example" };
new URL(cfg.publicBaseUrl); // throws early if malformed Type guard
function hasDirectImageUrl(data: unknown): boolean {
const r = data as Record<string, unknown>;
return ["direct_url", "directUrl", "url"].some((k) => typeof r?.[k] === "string" && (r[k] as string).trim().length > 0);
} Try / catch
try {
await uploader.upload(request);
} catch (err) {
if (err instanceof Error && /did not return a direct image URL/.test(err.message)) {
// inspect the endpoint's JSON schema and add publicBaseUrl or switch endpoints
}
throw err;
} Prevention
- Confirm the endpoint's response fields against direct_url/directUrl/url before adopting it
- Always set publicBaseUrl for id-only endpoints
- Version-pin or monitor the replacement service for schema changes
- Keep a probe test that uploads a tiny fixture and asserts a direct URL comes back
When it happens
Trigger: Upload to a config-compatible replacement endpoint returns JSON without direct_url/directUrl/url (or id+name with a configured publicBaseUrl), so 'raw' stays falsy after all fallbacks.
Common situations: Replacement service changed its JSON response schema; user configured a self-hosted clone that returns a different field name; publicBaseUrl option missing while the endpoint only returns ids.
Related errors
- the replacement endpoint rejected the upload
- the replacement endpoint omitted the uploaded URL
- the upload response omitted URL components
- the replacement endpoint returned no direct URL
- flickr response did not include a photo ID
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/32d68a18c2e430ff.
Report an issue: GitHub.