{"record":{"id":"8a7ba18ff2430299","repo":"ruvnet/ruflo","slug":"web3-storage-upload-failed-response-status-e","errorCode":null,"errorMessage":"Web3.storage upload failed: ${response.status} ${error}","messagePattern":"Web3\\.storage upload failed: (.+?) (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/transfer/ipfs/upload.ts","lineNumber":115,"sourceCode":"    Buffer.from(`--${boundary}\\r\\n`),\n    Buffer.from(`Content-Disposition: form-data; name=\"file\"; filename=\"${name}\"\\r\\n`),\n    Buffer.from(`Content-Type: application/json\\r\\n\\r\\n`),\n    content,\n    Buffer.from(`\\r\\n--${boundary}--\\r\\n`),\n  ]);\n\n  const response = await fetch(`${endpoint}/upload`, {\n    method: 'POST',\n    headers: {\n      'Authorization': `Bearer ${token}`,\n      'Content-Type': `multipart/form-data; boundary=${boundary}`,\n    },\n    body,\n  });\n\n  if (!response.ok) {\n    const error = await response.text();\n    throw new Error(`Web3.storage upload failed: ${response.status} ${error}`);\n  }\n\n  const result = await response.json() as { cid: string };\n  const cid = result.cid;\n  const gateway = options.gateway || 'https://w3s.link';\n\n  console.log(`[IPFS] Upload complete!`);\n  console.log(`[IPFS] CID: ${cid}`);\n\n  return {\n    cid,\n    size: content.length,\n    gateway,\n    pinnedAt: new Date().toISOString(),\n    url: `${gateway}/ipfs/${cid}`,\n  };\n}\n","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/transfer/ipfs/upload.ts#L97-L133","documentation":"uploadToWeb3Storage() POSTs a multipart body to `${endpoint}/upload` (default https://api.web3.storage/upload) with an Authorization: Bearer token. When the HTTP response is not ok, the response body text is appended to the status code and thrown. So this is the upstream API rejecting the request: 401 for a bad/expired token, 4xx for malformed payloads, 5xx for outages. Note web3.storage's classic upload API has been deprecated/sunset by Protocol Labs, so non-200s are now common with old tokens.","triggerScenarios":"Uploading with an expired or revoked WEB3_STORAGE_TOKEN (401); uploading after the web3.storage classic service was deprecated (the endpoint no longer accepts uploads); oversized or malformed content producing 4xx; transient 5xx during an API incident.","commonSituations":"Tokens that worked historically now failing because the service shut down; free-tier limits hit; copied credentials from another account; corporate proxies returning 403/502 on the POST.","solutions":["Read the status code in the message: 401/403 means regenerate the token and update WEB3_STORAGE_TOKEN","If it is a persistent failure on a legacy token, migrate providers — pinata (PINATA_API_KEY/PINATA_API_SECRET) or a local IPFS node (IPFS_API_URL) are built-in alternatives","For 5xx, retry after a backoff interval","Confirm the endpoint if you set a custom one via options.endpoint"],"exampleFix":"// before\nconst result = await uploadToIPFS(content, { provider: 'web3' }); // 401 -> Web3.storage upload failed: 401 ...\n\n// after\nlet result;\ntry {\n  result = await uploadToIPFS(content, { provider: 'web3' });\n} catch (e) {\n  if (/Web3\\.storage upload failed/.test(String(e?.message))) {\n    result = await uploadToIPFS(content, { provider: 'pinata' }); // fallback provider\n  } else throw e;\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"const isWeb3Failure = (e: unknown) => /Web3\\.storage upload failed: (\\d+)/.test(String((e as Error)?.message));\n\ntry {\n  result = await uploadToIPFS(content, { provider: 'web3' });\n} catch (e) {\n  if (!isWeb3Failure(e)) throw e;\n  const status = Number(/: (\\d+)/.exec(String((e as Error).message))?.[1]);\n  if (status === 401 || status === 403) throw new Error('web3.storage token invalid — refresh WEB3_STORAGE_TOKEN'); // not retryable\n  result = await uploadToIPFS(content, { provider: 'pinata' }); // 4xx/5xx -> fall back to another provider","preventionTips":["Treat 401/403 as configuration errors (rotate the token) and only 5xx as retryable — never blind-retry auth failures","Always configure a second provider (pinata or a local node via IPFS_API_URL) so uploads have a fallback path","Log the status code from the message before choosing retry vs fallback"],"tags":["ipfs","web3-storage","http","upload","api-error"],"backgroundTag":"http-request-failed","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}