tldraw/tldraw · error · Error
Could not stream object ${obj.Key}
Error message
Could not stream object ${obj.Key} What it means
After confirming Body exists, the script requires Body.transformToWebStream to pipe the R2 object into tar extract. Older AWS SDK v2 style bodies (Readable streams) lack transformToWebStream; the guard catches that incompatibility before attempting iteration.
Source
Thrown at internal/scripts/deploy-dotcom.ts:1063
objectsToFetch.map((k) => k.Key)
)
for (const obj of objectsToFetch) {
const { Body } = await R2.send(
new GetObjectCommand({
Bucket: R2_BUCKET,
Key: obj.Key,
})
)
if (!Body) {
throw new Error(`Could not fetch object ${obj.Key}`)
}
// pipe into untar
// `keep-existing` is important here because we don't want to overwrite the new assets
// if they have the same name as the old assets becuase they will have different sentry debugIds
// and it will mess up the inline source viewer on sentry errors.
const out = tar.x({ cwd: assetsDir, 'keep-existing': true })
if (!Body?.transformToWebStream) {
throw new Error(`Could not stream object ${obj.Key}`)
}
for await (const chunk of Body.transformToWebStream() as any as AsyncIterable<Uint8Array>) {
out.write(Buffer.from(chunk.buffer))
}
out.end()
}
}
main().catch(async (err) => {
// don't notify discord on preview builds
if (env.TLDRAW_ENV !== 'preview') {
await discord.message(`${Discord.AT_TEAM_MENTION} Deploy failed: ${err.stack}`, {
always: true,
})
}
console.error(err)
process.exit(1)
})View on GitHub (pinned to b31086b447)
Solutions
- Ensure @aws-sdk/client-s3 v3 (modular) is installed at the version declared in the workspace.
- If using an alternate S3 client, wrap its stream: `Readable.toWeb(Body)` to produce a web stream.
- Upgrade Node to >=22.12 (repo requirement) for native web stream support.
Example fix
// before
if (!Body?.transformToWebStream) {
throw new Error(`Could not stream object ${obj.Key}`)
}
// after (fall back to Node stream conversion)
const webStream = Body.transformToWebStream
? Body.transformToWebStream()
: Readable.toWeb(Body) Defensive patterns
Strategy: fallback
Validate before calling
// Detect stream capability before iterating
if (typeof Body?.transformToWebStream !== 'function' && typeof Body?.pipe !== 'function') {
throw new Error(`Object body has no usable stream interface: ${obj.Key}`)
} Type guard
function isWebStreamBody(Body: unknown): Body is { transformToWebStream: () => ReadableStream } {
return Boolean(Body && typeof (Body as any).transformToWebStream === 'function')
} Prevention
- Pin @aws-sdk/client-s3 v3 so Body always exposes transformToWebStream.
- Maintain a Node-version >= 22.12 requirement (already a repo rule) for web stream support.
- If you support alternate S3 clients, normalize the body to a web stream via Readable.toWeb.
When it happens
Trigger: Using a stream type that doesn't expose transformToWebStream (AWS SDK v2, or a mocked/test double); SDK downgrade or polyfill removing the method.
Common situations: @aws-sdk/client-s3 major version mismatch; running the script under a Node version or runtime without web streams; third-party S3-compatible client returning a Node Readable.
Related errors
- Could not fetch object ${obj.Key}
- Failed to delete ${result.Errors.length} objects: ${JSON.str
- Failed to upload image
- No persisted snapshot for ${slug}
- File not found
AI-assisted analysis of tldraw/tldraw@b31086b447 (2026-08-12).
Data as JSON: /api/errors/1048d3b9681d7077.
Report an issue: GitHub.