affaan-m/ECC · warning · Error
Choose exactly one memory body source: --stdin or --body-fil
Error message
Choose exactly one memory body source: --stdin or --body-file.
What it means
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.
Source
Thrown at scripts/memory.js:197
wait(retryDelayMs);
remainingRetryWaitMs -= retryDelayMs;
continue;
}
if (bytesRead === 0) break;
chunks.push(buffer.subarray(0, bytesRead));
total += bytesRead;
}
if (total > maxBytes) {
throw new Error(`memory body is too large (maximum ${maxBytes} bytes).`);
}
return decodeUtf8(Buffer.concat(chunks, total), 'memory body from standard input');
}
function readBody(options) {
const sources = [Boolean(options.stdin), Boolean(options.bodyFile)]
.filter(Boolean).length;
if (sources !== 1) {
throw new Error('Choose exactly one memory body source: --stdin or --body-file.');
}
if (options.stdin) {
return readBoundedStdin(MAX_BODY_BYTES);
}
const bodyPath = path.resolve(options.bodyFile);
return readRegularTextFile(bodyPath, {
label: '--body-file',
maxBytes: MAX_BODY_BYTES,
});
}
function writeJson(payload) {
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
}
function skipTerminalString(value, offset) {
let index = offset;View on GitHub (pinned to 01e15490f0)
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.
Example fix
# before ecc memory save --title "notes" # no body source # or ecc memory save --title "notes" --stdin --body-file notes.md # after — exactly one source ecc memory save --title "notes" --body-file notes.md
Defensive patterns
Strategy: validation
Validate before calling
function assertExactlyOneBodySource(options) {
const n = [Boolean(options.stdin), Boolean(options.bodyFile)].filter(Boolean).length;
if (n !== 1) throw new Error('Choose exactly one memory body source: --stdin or --body-file.');
} Try / catch
try { body = readBody(options); }
catch (err) { if (/Choose exactly one memory body source/.test(err.message)) { usage(2); } else throw err; } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ${label} must be a positive integer
- Unknown install target: ${parsed.target}. Expected one of ${
- Invalid ${flagName}: ${value}
- Invalid format: ${parsed.format}. Use text, json, or markdow
- --write requires --json, --markdown, or --format json|markdo
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/c6daa25d6abb1533.
Report an issue: GitHub.