{"record":{"id":"10ef14826c3503eb","repo":"santifer/career-ops","slug":"name-is-required","errorCode":null,"errorMessage":"--${name} is required","messagePattern":"--(.+?) is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"assessment-log.mjs","lineNumber":113,"sourceCode":"  }\n  return {\n    assessments: rows,\n    aggregates: { byPlatform },\n    quality: {\n      total: rows.length,\n      staleFlagged,\n      withoutScore: rows.filter(r => r.score === null).length,\n      withoutThreshold: rows.filter(r => r.threshold === null).length,\n      malformedLines: malformed,\n    },\n  };\n}\n\n// --- Append (`add` subcommand) ---\nexport function buildRow(fields, today) {\n  const req = (name) => {\n    const v = String(fields[name] ?? '').trim();\n    if (!v) throw new Error(`--${name} is required`);\n    if (v.includes('\\t') || v.includes('\\n')) throw new Error(`--${name} must not contain tabs or newlines`);\n    return v;\n  };\n  const opt = (name) => {\n    const v = String(fields[name] ?? '').trim();\n    if (v.includes('\\t') || v.includes('\\n')) throw new Error(`--${name} must not contain tabs or newlines`);\n    return v || '-';\n  };\n  const optPct = (name) => {\n    const v = String(fields[name] ?? '').trim();\n    if (!v) return '-';\n    if (parsePct(v) === null) throw new Error(`--${name} must be a percentage (e.g. 70 or 70%), got \"${v}\"`);\n    return v;\n  };\n  return [\n    today, req('company'), opt('report'), req('platform'), req('subject'),\n    optPct('threshold'), optPct('score'), opt('stale') === '-' ? '' : opt('stale'),\n  ].join('\\t');","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/assessment-log.mjs#L95-L131","documentation":"Validation in the `req` helper inside `buildRow` (assessment-log.mjs `add` subcommand). The required fields — `company`, `platform`, `subject` — must each be present and non-empty (after trim). Empty/missing values throw `--<name> is required` so the TSV row is never written with a blank mandatory column.","triggerScenarios":"Invoking the `add` subcommand without `--company`, `--platform`, or `--subject`; passing `--company \"\"` or whitespace-only; programmatically calling `buildRow({ company: '', platform: 'leetcode', subject: 'algo' }, today)`.","commonSituations":"User forgets one of the three mandatory flags; agent generates the command but a field is empty; shell quoting collapses a value to empty; copying a template command and missing a field.","solutions":["Always supply `--company`, `--platform`, and `--subject` with non-empty values when running `add`.","Run `node assessment-log.mjs add --help` (or read usage) to see required vs optional fields.","Validate in your caller before invoking: `['company','platform','subject'].forEach(k => { if (!fields[k]?.trim()) throw ... })`.","Generate the command only after all three values are confirmed non-empty.","Add a test asserting the missing-field rejection."],"exampleFix":"// before\nnode assessment-log.mjs add --platform leetcode --subject arrays\n// after\nnode assessment-log.mjs add --company acme --platform leetcode --subject arrays --threshold 70 --score 85","handlingStrategy":"validation","validationCode":"const REQUIRED = ['company', 'platform', 'subject'];\nfunction ensureRequired(fields) {\n  for (const k of REQUIRED) {\n    if (!String(fields[k] ?? '').trim()) throw new Error(`--${k} is required`);\n  }\n}","typeGuard":"function hasRequiredAssessmentFields(f) {\n  return ['company', 'platform', 'subject'].every(k =>\n    typeof f[k] === 'string' && f[k].trim() !== '');\n}","tryCatchPattern":null,"preventionTips":["Run `add --help` to see which flags are mandatory.","Build the command only after company/platform/subject are confirmed non-empty.","Validate the field map before invoking buildRow.","Test that omitting any one of the three throws."],"tags":["validation","cli","assessment-log","required-fields"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}