fix: prevent stack overflow in toBase64 for large inputs in non-Node environments#963
Open
claygeo wants to merge 1 commit intoanthropics:mainfrom
Open
fix: prevent stack overflow in toBase64 for large inputs in non-Node environments#963claygeo wants to merge 1 commit intoanthropics:mainfrom
claygeo wants to merge 1 commit intoanthropics:mainfrom
Conversation
…environments String.fromCharCode.apply(null, data) passes the entire Uint8Array as function arguments, which exceeds the JS engine's max argument limit (~65536) for inputs larger than ~100KB. This causes a "Maximum call stack size exceeded" RangeError in browsers and Cloudflare Workers when encoding large payloads (e.g. image uploads). The fix processes the Uint8Array in 32KB chunks before joining and encoding, which stays well within the argument limit while preserving identical output. Node.js environments are unaffected as they use Buffer.from() which has no such limitation. Closes anthropics#932
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
toBase64insrc/internal/utils/base64.tscrashes withRangeError: Maximum call stack size exceededwhen encoding inputs larger than ~100KB in non-Node environments (browsers, Cloudflare Workers, Deno, etc.).Reproduction:
This affects any use case that sends large payloads through the SDK in browser environments, most commonly image uploads via base64 encoding.
Root Cause
Line 18 uses
String.fromCharCode.apply(null, data), which spreads the entireUint8Arrayas individual function arguments. JavaScript engines have a maximum argument limit (typically ~65,536), so any input larger than ~64KB overflows the call stack.Node.js environments are unaffected because they hit the
Buffer.from()path on line 10, which has no such limitation.Solution
Process the
Uint8Arrayin 32KB chunks (0x8000 bytes), convert each chunk separately withString.fromCharCode.apply(), then join before passing tobtoa(). This stays well within the argument limit while producing identical output.This is a well-established pattern used by libraries like
js-base64, Firebase SDK, and others that need to encode large binary data in browser environments.Note on Generated Code
This file is marked as generated by Stainless. The fix should ideally be upstreamed to the code generator to persist across regenerations. In the meantime, this patch fixes the bug for current users.
Test Plan
toBase64(new Uint8Array(0))→ empty string ✅toBase64(new Uint8Array(100))→ valid base64 (small input, existing behavior) ✅toBase64(new Uint8Array(200 * 1024))→ valid base64 without stack overflow ✅toBase64("hello")→ string path unaffected ✅Closes #932