{"record":{"id":"a23c11fabdb8f095","repo":"can1357/oh-my-pi","slug":"the-discovery-endpoint-rejected-the-upload-request","errorCode":null,"errorMessage":"the discovery endpoint rejected the upload request","messagePattern":"the discovery endpoint rejected the upload request","errorType":"exception","errorClass":"LegacyDestinationError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/uploaders-legacy.ts","lineNumber":425,"sourceCode":"\t\t\t}\n\t\t},\n\t};\n}\n\nasync function discoverSendSpaceNode(config: DestinationRuntimeConfig, endpoint: URL): Promise<SendSpaceNode> {\n\tconst destination = \"sendspace\" as const;\n\tconst discovery = new URL(endpoint);\n\tdiscovery.searchParams.set(\"method\", \"anonymous.uploadGetInfo\");\n\tdiscovery.searchParams.set(\"speed_limit\", \"0\");\n\tdiscovery.searchParams.set(\"api_version\", \"1.0\");\n\tdiscovery.searchParams.set(\"app_version\", \"1.0\");\n\tconst apiKey = credentialString(config, \"apiKey\");\n\tif (apiKey) discovery.searchParams.set(\"api_key\", apiKey);\n\tconst response = await fetchFor(config)(discovery, { method: \"GET\" });\n\tawait expectOk(response, destination);\n\tconst xml = await response.text();\n\tif (/\\bstatus=(?:\"fail\"|'fail')/i.test(xml)) {\n\t\tthrow new LegacyDestinationError(destination, \"the discovery endpoint rejected the upload request\");\n\t}\n\tconst rawUrl = xmlAttribute(xml, \"upload\", \"url\");\n\tconst maxFileSize = xmlAttribute(xml, \"upload\", \"max_file_size\");\n\tconst uploadIdentifier = xmlAttribute(xml, \"upload\", \"upload_identifier\");\n\tconst extraInfo = xmlAttribute(xml, \"upload\", \"extra_info\");\n\tif (!rawUrl || !maxFileSize || !uploadIdentifier || !extraInfo) {\n\t\tthrow new LegacyDestinationError(destination, \"the discovery endpoint returned incomplete upload-node metadata\");\n\t}\n\treturn {\n\t\turl: new URL(httpUrl(destination, rawUrl)),\n\t\tmaxFileSize,\n\t\tuploadIdentifier,\n\t\textraInfo,\n\t};\n}\n\nfunction createSendSpaceUploader(config: DestinationRuntimeConfig, endpoint: URL): BlobUploader {\n\tconst destination = \"sendspace\" as const;","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/uploaders-legacy.ts#L407-L443","documentation":"Thrown during the SendSpace-style discovery phase: the uploader GETs the endpoint's API (optionally with api_key) expecting an XML document describing the upload URL. If the XML contains status=\"fail\" (quoted, case-insensitive), the discovery request itself was rejected — usually an authentication problem — before any file upload is attempted.","triggerScenarios":"GET to the configured sendspace-compatible discovery endpoint returns XML with status=\"fail\"/'fail' — invalid api_key, wrong token, or the private API refusing the request.","commonSituations":"Missing or wrong apiKey in destination credentials; pointing the endpoint at a SendSpace clone whose auth differs; api_key passed in query but the service expects it as POST; account suspended.","solutions":["Set/fix the apiKey credential for the sendspace destination","Inspect the returned XML (wrapped as failure cause) for the detailed error element","Confirm the private endpoint expects api_key as a GET query parameter","Ensure the endpoint host is not the deprecated public api.sendspace.com (blocked separately)","Test the discovery URL manually in a browser/curl to see the failure detail"],"exampleFix":"// before: no key configured\nconfig: { endpoint: \"https://my-clone.example/api\" }\n// after\nconfig: { endpoint: \"https://my-clone.example/api\", credentials: { apiKey: process.env.SENDSPACE_KEY } }","handlingStrategy":"try-catch","validationCode":"if (!apiKey) throw new Error(\"sendspace-compatible discovery requires an apiKey credential\");\n// also ensure the endpoint is private, not the blocked public API\nif (/api\\.sendspace\\.com$/.test(new URL(endpoint).hostname)) throw new Error(\"use a private discovery endpoint\");","typeGuard":null,"tryCatchPattern":"try {\n\tawait uploader.upload(request);\n} catch (err) {\n\tif (err instanceof Error && /discovery endpoint rejected the upload request/.test(err.message) && err.cause) {\n\t\tconst xml = String(err.cause);\n\t\tconst detail = xml.match(/<error[^>]*>([^<]+)<\\/error>/)?.[1];\n\t\tlogger.warn(\"discovery failed\", { detail });\n\t}\n\tthrow err;\n}","preventionTips":["Configure a valid apiKey for the sendspace-compatible service","Never use the deprecated public api.sendspace.com host","Verify the discovery endpoint accepts api_key as a GET query parameter","Capture and review the XML error element when discovery fails"],"tags":["upload","discovery","upstream-rejection","xml","sendspace"],"backgroundTag":"upload-rejected-by-upstream","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}