{"record":{"id":"cebb21b90a6d64a9","repo":"nanocoai/nanoclaw","slug":"stdin-json-input-is-not-valid-json","errorCode":null,"errorMessage":"--stdin-json input is not valid JSON","messagePattern":"--stdin-json input is not valid JSON","errorType":"validation","errorClass":"StdinJsonInputError","httpStatus":null,"severity":"error","filePath":"container/agent-runner/src/cli/stdin-json.ts","lineNumber":72,"sourceCode":"      throw new StdinJsonInputError(`--stdin-json input exceeds ${MAX_STDIN_JSON_BYTES} bytes`);\n    }\n    chunks.push(buffer);\n  }\n\n  return Buffer.concat(chunks, byteLength).toString('utf8');\n}\n\n/** Parse the input, requiring exactly one JSON object — not an array, scalar, or null. */\nfunction parseJsonObject(source: string): Record<string, unknown> {\n  if (source.trim().length === 0) {\n    throw new StdinJsonInputError('--stdin-json input is empty');\n  }\n\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(source);\n  } catch (err) {\n    throw new StdinJsonInputError('--stdin-json input is not valid JSON', { cause: err });\n  }\n\n  if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n    throw new StdinJsonInputError('--stdin-json input must be one JSON object');\n  }\n\n  return parsed as Record<string, unknown>;\n}\n\n/** Match the key normalization applied by command parsers in crud.ts. */\nfunction canonicalArgKey(key: string): string {\n  return key.replace(/-/g, '_');\n}\n\n/**\n * Reject any stdin key that could collide with another arg after the merge.\n *\n * Command parsers (crud.ts) normalize `-` to `_` in arg keys, so `group-id`","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/container/agent-runner/src/cli/stdin-json.ts#L54-L90","documentation":"parseMemoryMb throws when the CONTAINER_MEMORY_LIMIT env var does not match Docker's size-string grammar (number + optional b/k/m/g unit). It fails closed because returning undefined would silently remove the operator's memory cap — the one wrong direction for a resource limit to fail in.","triggerScenarios":"composeSessionSpec() reads CONTAINER_MEMORY_LIMIT and the value fails the regex /^(\\d+(?:\\.\\d+)?)\\s*([bkmg]?)b?$/i — e.g. '8 gb', 'limit=8g', '-512m', 'unlimited', or an empty-ish string.","commonSituations":"Typos in .env ('8GB' with a space, '8 g'), copy-paste from docs with units like '8GiB' or '512MB ' , or leftover placeholder values.","solutions":["Set CONTAINER_MEMORY_LIMIT to a plain docker size string like 8g, 512m, or 1073741824","Set it to 0 to explicitly disable the cap","Remove stray units/spaces: use '8g' not '8 gb' or '8GiB'"],"exampleFix":"# before\nCONTAINER_MEMORY_LIMIT=8 GiB\n\n# after\nCONTAINER_MEMORY_LIMIT=8g","handlingStrategy":"validation","validationCode":"if (process.env.CONTAINER_MEMORY_LIMIT && !/^\\d+(?:\\.\\d+)?\\s*[bkmg]?b?$/i.test(process.env.CONTAINER_MEMORY_LIMIT.trim())) {\n  throw new Error('CONTAINER_MEMORY_LIMIT must be a docker size string like 8g or 512m');\n}","typeGuard":"function isDockerSizeString(v: string): boolean {\n  return /^\\d+(?:\\.\\d+)?\\s*[bkmg]?b?$/i.test(v.trim()) && Number.isFinite(Number(v));\n}","tryCatchPattern":null,"preventionTips":["Validate .env at startup, not at first spawn","Use bare units: 8g, 512m, 1073741824; use 0 for no cap"],"tags":["docker","memory-limit","env-var","configuration"],"backgroundTag":"invalid-env-var-value","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}