{"record":{"id":"213afded096502e1","repo":"Budibase/budibase","slug":"no-response-received-for-attachment","errorCode":null,"errorMessage":"No response received for attachment","messagePattern":"No response received for attachment","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/backend-core/src/objectStore/utils.ts","lineNumber":77,"sourceCode":"    Rules: [lifecycleRule],\n  }\n\n  return {\n    Bucket: bucketName,\n    LifecycleConfiguration: lifecycleConfiguration,\n  }\n}\n\nasync function processUrlAttachment(\n  attachment: AutomationAttachment\n): Promise<AutomationAttachmentContent> {\n  const response = await fetchWithBlacklist(attachment.url)\n  if (!response.ok || !response.body) {\n    throw new Error(`Unexpected response ${response.statusText}`)\n  }\n  const fallbackFilename = path.basename(new URL(attachment.url).pathname)\n  if (!response.body) {\n    throw new Error(\"No response received for attachment\")\n  }\n  if (!(response.body instanceof stream.Readable)) {\n    throw new Error(\"Unexpected response body stream type\")\n  }\n  return {\n    filename: attachment.filename || fallbackFilename,\n    content: response.body,\n  }\n}\n\nexport async function processObjectStoreAttachment(\n  attachment: AutomationAttachment\n): Promise<BucketedContent> {\n  const result = objectStore.extractBucketAndPath(attachment.url)\n\n  if (result === null) {\n    throw new Error(\"Invalid signed URL\")\n  }","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/backend-core/src/objectStore/utils.ts#L59-L95","documentation":"After confirming the response is OK, processUrlAttachment double-checks that response.body is present; if the body is falsy despite the OK status, it throws 'No response received for attachment'. This guards against servers returning a success status with an empty body.","triggerScenarios":"fetchWithBlacklist returns an OK response with body === null — e.g. 204 No Content responses, servers responding 200 to a failed transfer, or undici/fetch quirks where body is consumed or absent.","commonSituations":"Automation attachment URLs pointing at APIs that return 204 or empty 200s, endpoints that expect different methods (POST vs GET) so they return empty bodies, or download servers that already streamed the body elsewhere.","solutions":["Confirm the URL returns a real file body with curl -i (check Content-Length > 0)","Point the attachment at a direct file link rather than an API endpoint returning 204","Check HTTP method/headers required by the host — some hosts only stream bodies with proper Accept/Range headers","Retry the automation step in case of a transient empty response"],"exampleFix":"// before\nattachments: [{ url: \"https://example.com/api/export\" }]\n// after\nattachments: [{ url: \"https://example.com/api/export?download=1\" }] // endpoint that streams the file","handlingStrategy":"validation","validationCode":"const res = await fetch(url)\nconst buf = await res.arrayBuffer()\nif (!res.ok || buf.byteLength === 0) throw new Error(\"Attachment URL returns empty body\")","typeGuard":"function hasBody<T extends { body: unknown }>(r: T): r is T & { body: NonNullable<T[\"body\"]> } {\n  return !!r.body\n}","tryCatchPattern":"try {\n  const content = await processUrlAttachment(attachment)\n} catch (err) {\n  if (err.message === \"No response received for attachment\") {\n    // host returned OK but empty body: use a direct download URL\n  }\n  throw err\n}","preventionTips":["Point attachments at direct file downloads, not API endpoints that may return 204","Check Content-Length > 0 when staging attachment URLs","Retest automation steps after changing remote endpoints","Use stable file-hosting for automation inputs"],"tags":["http","automation","attachments"],"backgroundTag":"http-non-ok-response","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}