Budibase/budibase · error
Could not read CSV
Error message
Could not read CSV
What it means
During CSV streaming, readCsv sets csvError=true when the stream emits an error event (a malformed/invalid CSV row) and the promise's catch converts that into 'Could not read CSV' to hide the low-level parser error. It signals the CSV content itself could not be parsed, as opposed to transport failures which are rethrown unchanged.
Source
Thrown at packages/server/src/integrations/s3.ts:274
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")
} else {
throw err
}
})
}
async delete(query: { bucket: string; delete: string }) {
return await this.client.deleteObjects({
Bucket: query.bucket,
Delete: JSON.parse(query.delete),
})
}
}
export default {
schema: SCHEMA,
integration: S3Integration,
}View on GitHub (pinned to a81a902e9a)
Solutions
- Open the S3 object and validate the CSV: check headers, quoting, delimiter, and that it is not an HTML/JSON error page — re-export the file correctly.
- Re-upload the file ensuring UTF-8 encoding and consistent quoting (e.g. export with standard CSV tooling).
- If the delimiter is non-comma, configure the query's CSV parsing options accordingly.
- Check the object is fully uploaded and not truncated (compare sizes/checksums).
Example fix
// before: CSV with inconsistent columns / stray quotes name,age "Alice,30 Bob,not,a,number // after: well-formed CSV re-exported name,age Alice,30 Bob,42
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate the object parses before ingesting
const lines = csvText.split("\n")
const cols = lines[0].split(",").length
if (lines.some(l => l.trim() && l.split(",").length !== cols)) {
throw new Error("Malformed CSV: inconsistent column counts")
} Type guard
function isCsvParseFailure(err: unknown): err is Error {
return err instanceof Error && err.message === "Could not read CSV"
} Try / catch
try {
const csv = await s3Integration.readCsv(query)
} catch (err) {
if (err instanceof Error && err.message === "Could not read CSV") {
// re-export/repair the source file, then retry
} else { throw err }
} Prevention
- Export CSVs with standard tooling and UTF-8 encoding
- Match the query's delimiter/quote settings to the actual file format
- Checksum-compare uploads to catch truncated files
- Open the object and confirm it is CSV, not an HTML/JSON error page
When it happens
Trigger: The fileStream emits an 'error' event while piping rows (csvError flag set) — i.e. the parser rejects the CSV content mid-stream during an S3 read CSV query execution.
Common situations: Downloading a CSV with inconsistent column counts, wrong delimiter/quote characters, non-UTF8 encoding, or an HTML/JSON error page saved as .csv; truncated uploads; exporting tool produced malformed quoting that the CSV parser rejects.
Related errors
- Unable to retrieve CSV - invalid stream
- Unable to determine delimiter
- Unable to retrieve stream - invalid response
- Error constructing OIDC refresh strategy: message=${err.mess
- Access denied to object store bucket.${err}
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/e16983677976f366.
Report an issue: GitHub.