nanocoai/nanoclaw · error · StdinJsonInputError
--stdin-json input exceeds ${MAX_STDIN_JSON_BYTES} bytes
Error message
--stdin-json input exceeds ${MAX_STDIN_JSON_BYTES} bytes What it means
readBounded streams stdin for --stdin-json and enforces MAX_STDIN_JSON_BYTES; exceeding the cap aborts before parsing to bound memory use.
Source
Thrown at src/cli/stdin-json.ts:54
* therefore normalized to a Buffer and the running total counts
* `buffer.byteLength` — the true encoded size — rather than string length,
* where a multibyte character (e.g. "ש", 2 bytes) would count as 1.
*
* Decoding to text happens exactly once, after the whole input is collected:
* a chunk boundary can fall in the middle of a multibyte character, so
* decoding chunk-by-chunk could corrupt the character that straddles the
* split. The limit check runs before buffering grows past the cap, so an
* oversized (or unbounded) pipe is rejected without being read to the end.
*/
async function readBounded(stream: StdinJsonStream): Promise<string> {
const chunks: Buffer[] = [];
let byteLength = 0;
for await (const chunk of stream) {
const buffer = typeof chunk === 'string' ? Buffer.from(chunk, 'utf8') : Buffer.from(chunk);
byteLength += buffer.byteLength;
if (byteLength > MAX_STDIN_JSON_BYTES) {
throw new StdinJsonInputError(`--stdin-json input exceeds ${MAX_STDIN_JSON_BYTES} bytes`);
}
chunks.push(buffer);
}
return Buffer.concat(chunks, byteLength).toString('utf8');
}
/** Parse the input, requiring exactly one JSON object — not an array, scalar, or null. */
function parseJsonObject(source: string): Record<string, unknown> {
if (source.trim().length === 0) {
throw new StdinJsonInputError('--stdin-json input is empty');
}
let parsed: unknown;
try {
parsed = JSON.parse(source);
} catch (err) {
throw new StdinJsonInputError('--stdin-json input is not valid JSON', { cause: err });View on GitHub (pinned to 294ef2aee8)
Solutions
- Shrink the payload — remove large blobs or move big data to a file path the command references instead
- Split into multiple smaller operations
- Pipe the correct, intended JSON file
Example fix
# before cat huge-payload.json | ncl groups update --id g1 --stdin-json # after ncl groups update --id g1 --name newname
Defensive patterns
Strategy: validation
Validate before calling
const size = fs.statSync(path).size;
if (size > MAX_STDIN_JSON_BYTES) throw new Error('payload too large; move data to a file path'); Prevention
- Keep --stdin-json payloads to plain args, not embedded blobs
When it happens
Trigger: Piping a JSON document larger than MAX_STDIN_JSON_BYTES to `ncl ... --stdin-json` (e.g. a huge embedded payload, base64 blob, or accidental binary file).
Common situations: Embedding large assets in a create/update payload, or accidentally piping a log/CSV instead of the intended small object.
Related errors
- --stdin-json input is empty
- --stdin-json input is not valid JSON
- --stdin-json input must be one JSON object
- --stdin-json key "__proto__" is not allowed
- --stdin-json key "${key}" is also supplied on argv
AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28).
Data as JSON: /api/errors/f0359b2e59d4172a.
Report an issue: GitHub.