{"record":{"id":"dd6c27cb5b216b9b","repo":"affaan-m/ECC","slug":"title-is-required","errorCode":null,"errorMessage":"--title is required.","messagePattern":"--title is required\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"scripts/memory.js","lineNumber":414,"sourceCode":"function assertMutationAllowed(command) {\n  if (process.env.ECC_DRY_RUN === '1') {\n    throw new Error(\n      `memory ${command} is disabled in dry-run mode; no files were written.`\n    );\n  }\n}\n\nfunction runInitCommand({ command, options, positionals, roots }) {\n  requireNoPositionals(positionals, command);\n  return printInit(\n    initializeVault({ roots, scopes: options.scopes || undefined }),\n    options.json\n  );\n}\n\nfunction runWriteCommand({ command, options, positionals, roots }) {\n  requireNoPositionals(positionals, command);\n  if (!options.title) throw new Error('--title is required.');\n  if (command === 'handoff' && !options.from) {\n    throw new Error('--from is required for handoffs.');\n  }\n  if (command === 'handoff' && (!options.targets || options.targets.length === 0)) {\n    throw new Error('At least one --target is required for handoffs.');\n  }\n  return printWrite(\n    saveMemory(saveInput(options, command === 'handoff' ? 'handoff' : null), { roots }),\n    options.json\n  );\n}\n\nfunction runSearchCommand({ options, positionals, roots }) {\n  const query = positionals.join(' ');\n  return printSearch(query, searchMemories(query, {\n    roots,\n    scopes: options.scopes,\n    kinds: options.kinds,","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/memory.js#L396-L432","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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>`."],"exampleFix":"# before\necc memory save --body-file notes.md\n\n# after\necc memory save --title \"Release 2025-08 handoff\" --body-file notes.md","handlingStrategy":"validation","validationCode":"function assertTitle(options) {\n  if (!options.title || typeof options.title !== 'string' || options.title.trim() === '') {\n    throw new Error('--title is required.');\n  }\n  if (options.title.length > 200) throw new Error('--title must be at most 200 characters.');\n}","typeGuard":"/** @returns {t is string} */\nfunction isNonEmptyTitle(t) { return typeof t === 'string' && t.trim().length > 0 && t.length <= 200; }","tryCatchPattern":"try { runWriteCommand(parsed); }\ncatch (err) { if (/--title is required\\./.test(err.message)) { usage(2); } else throw err; }","preventionTips":["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."],"tags":["cli","memory-vault","required-field","validation"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}