Budibase/budibase · error
Unable to retrieve CSV - invalid stream
Error message
Unable to retrieve CSV - invalid stream
What it means
readCsv in the S3 integration validates that the GetObject response body can be transformed into a Node.js Readable stream before parsing CSV. If response.Body is undefined or the transformToWebStream() result is not a stream.Readable, there is nothing to pipe the CSV from, so the integration throws this error instead of failing obscurely downstream.
Source
Thrown at packages/server/src/integrations/s3.ts:256
Bucket: query.bucket,
Delimiter: query.delimiter,
Marker: query.marker,
MaxKeys: query.maxKeys,
Prefix: query.prefix,
})
return response.Contents
}
async readCsv(query: { bucket: string; key: string }) {
const response = await this.client.getObject({
Bucket: query.bucket,
Key: query.key,
})
const fileStream = response.Body?.transformToWebStream()
if (!fileStream || !(fileStream instanceof stream.Readable)) {
throw new Error("Unable to retrieve CSV - invalid stream")
}
let csvError = false
return new Promise((resolve, reject) => {
fileStream.on("error", (err: Error) => {
reject(err)
})
const response = csv()
.fromStream(fileStream)
.on("error", () => {
csvError = true
})
fileStream.on("end", () => {
resolve(response)
})
}).catch(err => {
if (csvError) {
throw new Error("Could not read CSV")View on GitHub (pinned to a81a902e9a)
Solutions
- Verify the object exists at the configured bucket/key (aws s3 ls s3://<bucket>/<key>) and that the key is correct in the query.
- Check the S3 integration credentials/permissions have s3:GetObject on the object.
- Ensure a supported @aws-sdk/client-s3 version is installed where response.Body implements transformToWebStream().
- If using an S3-compatible store (MinIO etc.), confirm the endpoint returns standard GetObject responses.
Example fix
// before: wrong key, object missing
const query = { bucket: "my-bucket", key: "exports/data.csv" }
// after: verify key exists and credentials have GetObject
aws s3 ls s3://my-bucket/exports/data.csv # then rerun the query with the confirmed key Defensive patterns
Strategy: validation
Validate before calling
import { HeadObjectCommand, S3Client } from "@aws-sdk/client-s3"
const s3 = new S3Client({})
await s3.send(new HeadObjectCommand({ Bucket: query.bucket, Key: query.key })) // throws if missing/no permission Type guard
function hasReadableBody(res: { Body?: unknown }): res is { Body: { transformToWebStream(): ReadableStream } } {
return !!res.Body && typeof (res.Body as any).transformToWebStream === "function"
} Try / catch
try {
const csv = await s3Integration.readCsv(query)
} catch (err) {
if (err instanceof Error && err.message === "Unable to retrieve CSV - invalid stream") {
// check bucket/key/permissions, then retry or surface config error
} else { throw err }
} Prevention
- Validate bucket/key against HeadObject before reading
- Grant s3:GetObject to the integration credentials
- Keep @aws-sdk/client-s3 on a supported, tested version
- Test S3-compatible endpoints (MinIO) for standard GetObject responses
When it happens
Trigger: Calling the S3 read CSV query where GetObject returns no Body (object missing/deleted, no read permission yielding a response without body in some SDK paths) or transformToWebStream() returns a non-Readable value (SDK version mismatch, e.g. @aws-sdk/client-s3 v3 with wrong stream wiring).
Common situations: Specifying a wrong bucket/key so the object doesn't exist; IAM credentials lacking s3:GetObject; upgrading or mismatching AWS SDK versions where response.Body type changed; reading from a non-S3-compatible endpoint returning unexpected body types.
Related errors
- Could not read CSV
- Access denied to object store bucket.${err}
- Unable to retrieve stream - invalid response
- Error constructing OIDC refresh strategy: message=${err.mess
- Unable to determine delimiter
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/d98a74977e9bcc79.
Report an issue: GitHub.