{"record":{"id":"a428ba8137dc446f","repo":"can1357/oh-my-pi","slug":"the-replacement-endpoint-rejected-the-upload","errorCode":null,"errorMessage":"the replacement endpoint rejected the upload","messagePattern":"the replacement endpoint rejected the upload","errorType":"exception","errorClass":"LegacyDestinationError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/uploaders-legacy.ts","lineNumber":242,"sourceCode":"\t\t\t}\n\t\t},\n\t};\n}\n\nfunction createPuushUploader(config: DestinationRuntimeConfig, endpoint: URL): BlobUploader {\n\tconst destination = \"puush\" as const;\n\tconst apiKey = requireCredential(config, \"apiKey\");\n\treturn {\n\t\tdestination,\n\t\tasync upload(request) {\n\t\t\ttry {\n\t\t\t\tconst body = multipartFile(request, \"f\", { k: apiKey, z: \"oh-my-pi\" });\n\t\t\t\tconst response = await fetchFor(config)(endpoint, { method: \"POST\", body });\n\t\t\t\tawait expectOk(response, destination);\n\t\t\t\tconst values = (await response.text()).trim().split(\",\");\n\t\t\t\tconst status = Number.parseInt(values[0] ?? \"\", 10);\n\t\t\t\tif (!Number.isInteger(status) || status < 0 || !values[1]) {\n\t\t\t\t\tthrow new LegacyDestinationError(destination, \"the replacement endpoint rejected the upload\");\n\t\t\t\t}\n\t\t\t\tconst url = httpUrl(destination, values[1]);\n\t\t\t\treturn publication(destination, request, url, values[2] ? { remoteId: values[2] } : undefined);\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 createMediaFireUploader(config: DestinationRuntimeConfig, endpoint: URL): BlobUploader {\n\tconst destination = \"mediafire\" as const;\n\tconst headers = optionalBasicHeaders(destination, config, \"username\", \"password\");\n\treturn {\n\t\tdestination,\n\t\tasync upload(request) {\n\t\t\ttry {\n\t\t\t\tconst fields: Record<string, string> = {};","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/uploaders-legacy.ts#L224-L260","documentation":"Thrown by the replacement-endpoint uploader (e.g. chevereto-style) when the server responds OK but its comma-separated 'status,url[,deleteUrl]' payload does not parse: the first field is not a non-negative integer or the URL field is missing. The library cannot construct a publication URL, so the upload is treated as rejected by the replacement endpoint.","triggerScenarios":"POST multipart 'f' with 'k' (apiKey) and 'z' branding to the user-configured endpoint; expectOk passes but response.text() splits on commas into an unparseable status or empty URL — e.g. body is 'error,Invalid key' or an HTML page.","commonSituations":"Wrong API key for the replacement host; endpoint returning an error page with 200 status; misconfigured endpoint pointing at a non-chevereto-style service; the service changing its response format.","solutions":["Check the endpoint URL and apiKey configured for this destination","Inspect the raw response text (it is embedded via failure()) to see what the server returned","Confirm the endpoint speaks the expected 'status,url[,deleteUrl]' CSV protocol","Point the destination at a service matching the expected response format"],"exampleFix":"// before: endpoint pointed at a generic host\nendpoint: \"https://example.com/api/upload\"\n// after: use the actual chevereto-compatible API endpoint with valid key\nendpoint: \"https://my-chevereto-host.example/api/upload\",\ncredentials: { apiKey: process.env.CHEVERETO_API_KEY }","handlingStrategy":"try-catch","validationCode":"// validate endpoint speaks the CSV protocol with a dry run or docs check\nif (!endpointUrl.pathname.includes(\"api\")) console.warn(\"endpoint may not follow the status,url CSV protocol\");","typeGuard":"function isCsvUploadResult(text: string): boolean {\n\tconst parts = text.trim().split(\",\");\n\tconst status = Number.parseInt(parts[0] ?? \"\", 10);\n\treturn Number.isInteger(status) && status >= 0 && Boolean(parts[1]);\n}","tryCatchPattern":"try {\n\tawait uploader.upload(request);\n} catch (err) {\n\tif (err instanceof Error && /replacement endpoint rejected the upload/.test(err.message) && err.cause) {\n\t\tconsole.error(\"raw endpoint response:\", err.cause);\n\t}\n\tthrow err;\n}","preventionTips":["Verify the replacement endpoint's response format before wiring it in","Use a valid apiKey for the replacement host","Test with curl -F to confirm 'status,url[,delete]' output","Keep endpoint config in one place to avoid typos"],"tags":["upload","response-parsing","custom-endpoint","legacy-destination"],"backgroundTag":"upload-rejected-by-upstream","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}