hcengineering/platform · error · TypeError
Unsupported data type
Error message
Unsupported data type
What it means
The private-to-module toBuffer helper accepts only Buffer, string, or Node Readable streams before upload; any other value (e.g. Uint8Array, Blob, plain object, or a browser ReadableStream) falls into the else branch and a TypeError('Unsupported data type') is thrown. It surfaces from storageClient.put() and buffer().
Source
Thrown at foundations/core/packages/api-client/src/storage/client.ts:178
method: 'DELETE',
headers: { ...this.headers }
})
}
}
async function toBuffer (data: Buffer | string | Readable): Promise<Buffer> {
if (Buffer.isBuffer(data)) {
return data
} else if (typeof data === 'string') {
return Buffer.from(data)
} else if (data instanceof Readable) {
const chunks: Buffer[] = []
for await (const chunk of data) {
chunks.push(chunk)
}
return Buffer.concat(chunks as any)
} else {
throw new TypeError('Unsupported data type')
}
}
async function wrappedFetch (url: string | URL, init?: RequestInit): Promise<Response> {
let response: Response
try {
response = await fetch(url, init)
} catch (error: any) {
throw new NetworkError(`Network error ${error}`)
}
if (!response.ok) {
const text = await response.text()
if (response.status === 404) {
throw new NotFoundError(text)
} else {
throw new StorageError(text)
}
}View on GitHub (pinned to 63e28dc964)
Solutions
- Convert the value before calling put: Buffer.from(await new Response(webStream).arrayBuffer()) for web streams.
- Use fs.createReadStream(path) for files, or Buffer.from(uint8array) / Buffer.from(await blob.arrayBuffer()) for typed arrays and Blobs.
- Ensure TypeScript compiles with the declared put signature (Readable | Buffer | string) so mismatches are caught at build time.
Example fix
// before const res = await fetch(fileUrl) await storage.put(name, res.body, contentType) // TypeError: Unsupported data type // after const res = await fetch(fileUrl) const buf = Buffer.from(await res.arrayBuffer()) await storage.put(name, buf, contentType)
Defensive patterns
Strategy: validation
Validate before calling
import { Readable } from 'stream'
function assertPutInput(data: unknown): asserts data is Buffer | string | Readable {
if (!Buffer.isBuffer(data) && typeof data !== 'string' && !(data instanceof Readable)) {
throw new TypeError(`put() needs Buffer | string | Readable, got ${data?.constructor?.name}`)
}
} Type guard
function isPutInput(data: unknown): data is Buffer | string | Readable {
return Buffer.isBuffer(data) || typeof data === 'string' || data instanceof Readable
} Try / catch
try {
await storage.put(name, data, contentType)
} catch (e) {
if (e instanceof TypeError && e.message === 'Unsupported data type') {
// convert and retry once
const buf = Buffer.from(await new Response(data as any).arrayBuffer())
return storage.put(name, buf, contentType)
}
throw e
} Prevention
- Coerce web streams/Blobs/Uint8Arrays to Buffer before calling put().
- Use Readable.from(webStream) (Node 18+) to adapt web streams in Node.
- Enable strict TypeScript so put() signature mismatches fail at compile time.
- Centralize file-input handling in one helper that always yields Buffer or Readable.
When it happens
Trigger: Calling storageClient.put(name, data, contentType) with data that is not Buffer/string/Readable — typically a Uint8Array, ArrayBuffer, Blob, or a web ReadableStream obtained from fetch response.body in a browser context.
Common situations: Passing response.body (a Web ReadableStream) directly to put(); passing a File/Blob from a browser file input; TypeScript types not enforced because the value came from an untyped API boundary; code written for a browser SDK reused in Node.
Related errors
- Cannot create message, group not found: cardId = ${event.car
- The "ws" package is required for NodeWebSocketFactory.
- Missing response body
- Network error ${error}
- await response.text()
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/aaf6db0cd861f00f.
Report an issue: GitHub.