You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
More useful error than toString failed when Buffer length greater than kMaxLength? #3175
I'm assuming there's some sort of memory constraint trying to convert buffers into strings?
$ uname -aDarwin ReBuke-Pro.local 15.0.0 Darwin Kernel Version 15.0.0: Wed Aug 26 16:57:32 PDT 2015; root:xnu-3247.1.106~1/RELEASE_X86_64 x86_64
$ node --versionv4.1.1
$ node -p 'new Buffer(268435440).toString().length'268435440
But:
$ node -p 'new Buffer(268435441).toString().length'buffer.js:378 throw new Error('toString failed'); ^Error: toString failed at Buffer.toString (buffer.js:378:11) at [eval]:1:23 at Object.exports.runInThisContext (vm.js:54:17) at Object.<anonymous> ([eval]-wrapper:6:22) at Module._compile (module.js:434:26) at node.js:566:27 at doNTCallback0 (node.js:407:9) at process._tickCallback (node.js:336:13)
Firstly, I'm not sure that this should even be an error (are we really only limited to 256MB? That's... not very much). This seems to have been addressed in the past, but I feel like a regression might have occurred: #1374 (comment)
But that aside, can we actually detect what the error is and report on it in a more detailed way? The current toString check provides little insight.
But is that the only error that can occur? Looking at the code at the moment, the check is pretty basic – is there no way of getting more detail as to why result may be undefined?
Not at the moment, no. The undefined value trickles down from StringBytes::Encode() in src/string_bytes.h. I don't think there are other code paths that return an empty Local<String> but I didn't check exhaustively.
FWIW, v8 (I assume?) spits out a slightly better error when trying to concat strings:
$ node -p 'var a = "a"; for (var i = 0; i < 27; i++) a = a + a; a.length'134217728
$ node -p 'var a = "a"; for (var i = 0; i < 28; i++) a = a + a; a.length'[eval]:1var a = "a"; for (var i = 0; i < 28; i++) a = a + a; a.length ^RangeError: Invalid string length at [eval]:1:49 at Object.exports.runInThisContext (vm.js:54:17) at Object.<anonymous> ([eval]-wrapper:6:22) at Module._compile (module.js:434:26) at node.js:566:27 at doNTCallback0 (node.js:407:9) at process._tickCallback (node.js:336:13)
Is the size limit exposed at all? If it were I'd be happy to add a PR that checks, in the case of an undefined result, whether the Buffer length is greater than it.
changed the title [-]More useful error than `toString failed`?[/-][+]More useful error than `toString failed` when Buffer length greater than kMaxLength?[/+]on Oct 4, 2015
For what it's worth, the error message here has been marginally improved to Error: "toString()" failed (although I'm not sure why the quotation marks are used--that seems peculiar--but the addition of parentheses are a marginal improvement).
And, of course, it still doesn't indicate why it failed though.
Reacted by Bill Morris, Aaron Cordova and Maxim Vorobjov
I am running into this issue when I try to download .tar file via request and piping it to tar.x(). Does this issue imply that the maximum body size that I can download via request.get() is 1G for 64-bit machine?
Activity
bnoordhuis commentedon Oct 4, 2015
256 MB is the limit for strings in V8 so no, it's not a regression. What would you report in more detail?
mhart commentedon Oct 4, 2015
Anything would be better than that TBH.
mhart commentedon Oct 4, 2015
It's not obvious to the user what's actually gone wrong.
How about "Cannot create string larger than 256MB"? Seems a lot clearer to me.
bnoordhuis commentedon Oct 4, 2015
I think a pull request to that effect would be acceptable.
mhart commentedon Oct 4, 2015
But is that the only error that can occur? Looking at the code at the moment, the check is pretty basic – is there no way of getting more detail as to why
resultmay beundefined?bnoordhuis commentedon Oct 4, 2015
Not at the moment, no. The undefined value trickles down from StringBytes::Encode() in src/string_bytes.h. I don't think there are other code paths that return an empty
Local<String>but I didn't check exhaustively.mhart commentedon Oct 4, 2015
FWIW, v8 (I assume?) spits out a slightly better error when trying to concat strings:
Is the size limit exposed at all? If it were I'd be happy to add a PR that checks, in the case of an
undefinedresult, whether the Buffer length is greater than it.targos commentedon Oct 4, 2015
I don't think it is exposed in JS. The exact limit is
(1 << 28) - 16(268435440) and is defined innode/deps/v8/include/v8.h
Line 2083 in 64beab0
[-]More useful error than `toString failed`?[/-][+]More useful error than `toString failed` when Buffer length greater than kMaxLength?[/+]MylesBorins commentedon Oct 6, 2015
I would love to take a stab at this if people are open to it.
/cc @jasnell
jasnell commentedon Oct 6, 2015
Works for me!
On Oct 6, 2015 12:49 PM, "Myles Borins" notifications@github.com wrote:
trevnorris commentedon Oct 6, 2015
@MylesBorins Seems the discussion addresses more than just the error message. Mind identifying the specifics of what you'll be working on?
MylesBorins commentedon Oct 6, 2015
I specifically was interested in a better error message when toString is called on a Buffer larger than kStringMaxLength
That seemed like a pretty easy one to knock out (I've basically got it done already).
mhart commentedon Oct 6, 2015
@MylesBorins I think the discussion was around how to detect the limit though – have you exposed
kMaxLength?27 remaining items
Trott commentedon Mar 23, 2017
For what it's worth, the error message here has been marginally improved to
Error: "toString()" failed(although I'm not sure why the quotation marks are used--that seems peculiar--but the addition of parentheses are a marginal improvement).And, of course, it still doesn't indicate why it failed though.
src: do proper StringBytes error handling
justinjdickow commentedon Jul 9, 2017
I... don't understand why the limit is 256 MB :(
mhart commentedon Jul 9, 2017
There's an issue open on v8 too, if you'd like to star it: https://bugs.chromium.org/p/v8/issues/detail?id=6148
justinjdickow commentedon Jul 9, 2017
Can we rename the issue from "String length limit is small-ish" to "String length limit is small-af"
mhart commentedon Jul 24, 2017
Great news! v8 has upped the limit to ~1GB on 64-bit archs: https://chromium-review.googlesource.com/c/570047
Hopefully it comes with a nicer error message when it fails too (although that's possibly still a Node.js responsibility?)
src: migrate string_bytes.cc to throw errors with code
joyeecheung commentedon Apr 7, 2018
After 63eb267 this now returns a message
Cannot create a string larger than 0x3fffffe7 byteswith the error code set toERR_STRING_TOO_LARGE.soichih commentedon Jan 7, 2019
I am running into this issue when I try to download .tar file via request and piping it to tar.x(). Does this issue imply that the maximum body size that I can download via request.get() is 1G for 64-bit machine?
soichih commentedon Jan 7, 2019
nvm.. I just had to set "encoding: null" ... which prevents the body to be passed to toString()
src: add error code helpers to src/node_errors.h