{"record":{"id":"c6daa25d6abb1533","repo":"affaan-m/ECC","slug":"choose-exactly-one-memory-body-source-stdin-or","errorCode":null,"errorMessage":"Choose exactly one memory body source: --stdin or --body-file.","messagePattern":"Choose exactly one memory body source: --stdin or --body-file\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"scripts/memory.js","lineNumber":197,"sourceCode":"      wait(retryDelayMs);\n      remainingRetryWaitMs -= retryDelayMs;\n      continue;\n    }\n    if (bytesRead === 0) break;\n    chunks.push(buffer.subarray(0, bytesRead));\n    total += bytesRead;\n  }\n  if (total > maxBytes) {\n    throw new Error(`memory body is too large (maximum ${maxBytes} bytes).`);\n  }\n  return decodeUtf8(Buffer.concat(chunks, total), 'memory body from standard input');\n}\n\nfunction readBody(options) {\n  const sources = [Boolean(options.stdin), Boolean(options.bodyFile)]\n    .filter(Boolean).length;\n  if (sources !== 1) {\n    throw new Error('Choose exactly one memory body source: --stdin or --body-file.');\n  }\n  if (options.stdin) {\n    return readBoundedStdin(MAX_BODY_BYTES);\n  }\n\n  const bodyPath = path.resolve(options.bodyFile);\n  return readRegularTextFile(bodyPath, {\n    label: '--body-file',\n    maxBytes: MAX_BODY_BYTES,\n  });\n}\n\nfunction writeJson(payload) {\n  process.stdout.write(`${JSON.stringify(payload, null, 2)}\\n`);\n}\n\nfunction skipTerminalString(value, offset) {\n  let index = offset;","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/memory.js#L179-L215","documentation":"readBody counts how many of --stdin and --body-file are truthy and requires exactly one; zero sources or both sources throws `Choose exactly one memory body source: --stdin or --body-file.` The XOR guard prevents ambiguity about where the memory body comes from and avoids silent precedence surprises.","triggerScenarios":"Calling `memory save --title x` with neither --stdin nor --body-file. Passing both: `memory save --title x --stdin --body-file notes.md`. A wrapper that always adds --stdin but the user also passed --body-file.","commonSituations":"Forgetting the body source entirely (most common). A default --stdin in an alias colliding with an explicit --body-file. Interactive use where neither pipe nor file was set up.","solutions":["Always supply exactly one body source per save/handoff.","For interactive use, prefer `--body-file <path>` to avoid TTY/stdin issues.","For piped content, use only `--stdin`.","Audit shell aliases/wrappers to ensure they do not auto-inject a second source."],"exampleFix":"# before\necc memory save --title \"notes\"   # no body source\n# or\necc memory save --title \"notes\" --stdin --body-file notes.md\n\n# after — exactly one source\necc memory save --title \"notes\" --body-file notes.md","handlingStrategy":"validation","validationCode":"function assertExactlyOneBodySource(options) {\n  const n = [Boolean(options.stdin), Boolean(options.bodyFile)].filter(Boolean).length;\n  if (n !== 1) throw new Error('Choose exactly one memory body source: --stdin or --body-file.');\n}","typeGuard":null,"tryCatchPattern":"try { body = readBody(options); }\ncatch (err) { if (/Choose exactly one memory body source/.test(err.message)) { usage(2); } else throw err; }","preventionTips":["Standardize on one source per workflow (pipe => --stdin, file => --body-file).","Audit aliases/wrappers so they never auto-inject a second source.","For interactive use, prefer --body-file to avoid stdin ambiguity."],"tags":["cli","argument-parsing","memory-vault","validation"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}