{"record":{"id":"54de84da2ae63a4a","repo":"Budibase/budibase","slug":"unable-to-retrieve-stream-invalid-response","errorCode":null,"errorMessage":"Unable to retrieve stream - invalid response","messagePattern":"Unable to retrieve stream - invalid response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/backend-core/src/objectStore/objectStore.ts","lineNumber":788,"sourceCode":"  return tmpPath\n}\n\nexport async function getReadStream(\n  bucketName: string,\n  path: string\n): Promise<{ stream: Readable; contentLength?: number; contentType?: string }> {\n  return await tracer.trace(\"getReadStream\", async span => {\n    bucketName = sanitizeBucket(bucketName)\n    path = sanitizeKey(path)\n    span.addTags({ bucketName, path })\n    const client = ObjectStore()\n    const params = {\n      Bucket: bucketName,\n      Key: path,\n    }\n    const response = await client.getObject(params)\n    if (!response.Body || !(response.Body instanceof stream.Readable)) {\n      throw new Error(\"Unable to retrieve stream - invalid response\")\n    }\n    span.addTags({\n      contentLength: response.ContentLength,\n      contentType: response.ContentType,\n    })\n    return {\n      stream: response.Body,\n\n      contentLength: response.ContentLength,\n      contentType: response.ContentType,\n    }\n  })\n}\n\nexport async function getObjectMetadata(\n  bucket: string,\n  path: string\n): Promise<HeadObjectCommandOutput> {","sourceCodeStart":770,"sourceCodeEnd":806,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/backend-core/src/objectStore/objectStore.ts#L770-L806","documentation":"getReadStream obtains an object from the store via the S3 client's getObject and requires the response Body to be an instance of stream.Readable (AWS SDK v3 should return a Readable). If the Body is missing or is not a Readable (e.g. it's a Blob/Uint8Array depending on SDK response type configuration), the function refuses to return a broken stream and throws.","triggerScenarios":"client.getObject returns successfully but response.Body is null/undefined, or Body is not a stream.Readable — typically when the object is empty, when the SDK response body type differs (requestStreamCollector/response body type mismatch), or an S3-compatible endpoint returns a non-standard response shape.","commonSituations":"Reading automation/file attachments from MinIO with a misconfigured endpoint, using an AWS SDK configuration where the body is deserialized as a Blob (e.g. browser-style SDK settings) instead of a Node stream, or reading an object that was truncated to zero bytes.","solutions":["Confirm you are running the Node build of the AWS SDK v3 with no response-body override (Body must be stream.Readable); check for conflicting @smithy/node-http-handler config","Verify the object exists and is non-empty in the bucket via a direct client headObject or console","If using MinIO, verify MINIO_URL and endpoint config so you are not hitting a gateway that returns malformed responses","Re-upload the object if it is zero-byte/corrupted"],"exampleFix":"// before\nconst { stream } = await objectStore.getReadStream(bucket, key)\n// after\nlet stream\ntry {\n  ;({ stream } = await objectStore.getReadStream(bucket, key))\n} catch (err) {\n  if (err.message.includes(\"Unable to retrieve stream\")) throw new Error(\"Object unavailable: \" + key)\n  throw err\n}","handlingStrategy":"type-guard","validationCode":"const meta = await objectStore.getObjectMetadata(bucket, path)\nif (!meta || (meta.ContentLength ?? 0) === 0) throw new Error(\"Object empty or missing\")","typeGuard":"function isNodeStream(b: unknown): b is import(\"stream\").Readable {\n  return b instanceof (await import(\"stream\")).Readable\n}","tryCatchPattern":"try {\n  const { stream } = await objectStore.getReadStream(bucket, path)\n} catch (err) {\n  if (err.message.includes(\"Unable to retrieve stream\")) {\n    // object missing or SDK returned non-stream body\n  }\n  throw err\n}","preventionTips":["Avoid overriding AWS SDK v3 response body deserialization in Node","Verify object size via metadata before streaming","Keep endpoint config (MinIO/S3) consistent across services","Do not polyfill fetch/stream globals in Node services"],"tags":["s3","stream","object-store"],"backgroundTag":"s3-empty-object-response","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}