{"record":{"id":"32d68a18c2e430ff","repo":"can1357/oh-my-pi","slug":"the-replacement-endpoint-did-not-return-a-direct-i","errorCode":null,"errorMessage":"the replacement endpoint did not return a direct image URL","messagePattern":"the replacement endpoint did not return a direct image URL","errorType":"exception","errorClass":"LegacyDestinationError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/uploaders-legacy.ts","lineNumber":306,"sourceCode":"\t\t\ttry {\n\t\t\t\tconst response = await fetchFor(config)(endpoint, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders,\n\t\t\t\t\tbody: multipartFile(request),\n\t\t\t\t});\n\t\t\t\tawait expectOk(response, destination);\n\t\t\t\tconst data = await jsonObject(destination, response);\n\t\t\t\tlet raw = firstString(data, [\"direct_url\", \"directUrl\", \"url\"]);\n\t\t\t\tif (!raw) {\n\t\t\t\t\tconst id = firstString(data, [\"id\"]);\n\t\t\t\t\tconst name = firstString(data, [\"name\"]);\n\t\t\t\t\tconst publicBase = optionString(config, \"publicBaseUrl\");\n\t\t\t\t\tif (id && name && publicBase) {\n\t\t\t\t\t\traw = `${publicBase.replace(/\\/$/, \"\")}/file/${encodeURIComponent(id)}/${encodeURIComponent(name)}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!raw)\n\t\t\t\t\tthrow new LegacyDestinationError(\n\t\t\t\t\t\tdestination,\n\t\t\t\t\t\t\"the replacement endpoint did not return a direct image URL\",\n\t\t\t\t\t);\n\t\t\t\tconst remoteId = firstString(data, [\"id\"]);\n\t\t\t\treturn publication(\n\t\t\t\t\tdestination,\n\t\t\t\t\trequest,\n\t\t\t\t\thttpUrl(destination, raw, endpoint),\n\t\t\t\t\tremoteId ? { remoteId } : undefined,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tthrow failure(destination, error);\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction createLambdaUploader(config: DestinationRuntimeConfig, endpoint: URL): BlobUploader {","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/uploaders-legacy.ts#L288-L324","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: endpoint returns only ids, no publicBaseUrl configured\nconfig: { endpoint: \"https://host.example/api/upload\", apiKey }\n// after: supply publicBaseUrl so id+name can form a URL\nconfig: { endpoint: \"https://host.example/api/upload\", apiKey, publicBaseUrl: \"https://host.example\" }","handlingStrategy":"validation","validationCode":"// ensure publicBaseUrl is set when your endpoint returns ids instead of direct URLs\nconst cfg = { endpoint, apiKey, publicBaseUrl: \"https://host.example\" };\nnew URL(cfg.publicBaseUrl); // throws early if malformed","typeGuard":"function hasDirectImageUrl(data: unknown): boolean {\n\tconst r = data as Record<string, unknown>;\n\treturn [\"direct_url\", \"directUrl\", \"url\"].some((k) => typeof r?.[k] === \"string\" && (r[k] as string).trim().length > 0);\n}","tryCatchPattern":"try {\n\tawait uploader.upload(request);\n} catch (err) {\n\tif (err instanceof Error && /did not return a direct image URL/.test(err.message)) {\n\t\t// inspect the endpoint's JSON schema and add publicBaseUrl or switch endpoints\n\t}\n\tthrow err;\n}","preventionTips":["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"],"tags":["upload","response-parsing","custom-endpoint","legacy-destination"],"backgroundTag":"incomplete-upload-response","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}