affaan-m/ECC · warning · Error
--title is required.
Error message
--title is required.
What it means
runWriteCommand (the handler for both save and handoff) calls requireNoPositionals then immediately requires options.title; if it is falsy (undefined/empty), it throws `--title is required.` Every saved memory needs a human-readable title for search/listing, so the command refuses to persist an untitled memory. handoff has additional requirements (--from, at least one --target) checked immediately after.
Source
Thrown at scripts/memory.js:414
function assertMutationAllowed(command) {
if (process.env.ECC_DRY_RUN === '1') {
throw new Error(
`memory ${command} is disabled in dry-run mode; no files were written.`
);
}
}
function runInitCommand({ command, options, positionals, roots }) {
requireNoPositionals(positionals, command);
return printInit(
initializeVault({ roots, scopes: options.scopes || undefined }),
options.json
);
}
function runWriteCommand({ command, options, positionals, roots }) {
requireNoPositionals(positionals, command);
if (!options.title) throw new Error('--title is required.');
if (command === 'handoff' && !options.from) {
throw new Error('--from is required for handoffs.');
}
if (command === 'handoff' && (!options.targets || options.targets.length === 0)) {
throw new Error('At least one --target is required for handoffs.');
}
return printWrite(
saveMemory(saveInput(options, command === 'handoff' ? 'handoff' : null), { roots }),
options.json
);
}
function runSearchCommand({ options, positionals, roots }) {
const query = positionals.join(' ');
return printSearch(query, searchMemories(query, {
roots,
scopes: options.scopes,
kinds: options.kinds,View on GitHub (pinned to 01e15490f0)
Solutions
- Always pass a non-empty `--title <text>` for save and handoff.
- Default it in wrappers only when non-empty: `--title "${TITLE:?title required}"`.
- Keep titles under MAX_TITLE_CHARS (200 chars) to avoid a downstream validation error.
- For handoffs also pass `--from <harness>` and at least one `--target <harness>`.
Example fix
# before ecc memory save --body-file notes.md # after ecc memory save --title "Release 2025-08 handoff" --body-file notes.md
Defensive patterns
Strategy: validation
Validate before calling
function assertTitle(options) {
if (!options.title || typeof options.title !== 'string' || options.title.trim() === '') {
throw new Error('--title is required.');
}
if (options.title.length > 200) throw new Error('--title must be at most 200 characters.');
} Type guard
/** @returns {t is string} */
function isNonEmptyTitle(t) { return typeof t === 'string' && t.trim().length > 0 && t.length <= 200; } Try / catch
try { runWriteCommand(parsed); }
catch (err) { if (/--title is required\./.test(err.message)) { usage(2); } else throw err; } Prevention
- Always pass `--title` for save/handoff; treat it as mandatory, not optional.
- In wrappers fail fast: `--title "${TITLE:?title required}"`.
- Keep titles concise (<=200 chars) to avoid the downstream length validation.
When it happens
Trigger: Running `ecc memory save --body-file notes.md` with no --title. Passing `--title ''` (empty string is falsy). A wrapper that builds args conditionally and omitted --title on a branch.
Common situations: Assuming the body filename or first line will be used as the title (it will not). Forgetting the flag in a quick save. A scripted save where TITLE was empty.
Related errors
- memory body must contain non-whitespace context.
- target harnesses must contain at least one harness or "all".
- Memory document ${sourcePath} is missing fields: ${missing.j
- Choose exactly one memory body source: --stdin or --body-fil
- ${label} must be a positive integer
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/dd6c27cb5b216b9b.
Report an issue: GitHub.