{"record":{"id":"e6b52396ef7d13b0","repo":"affaan-m/ECC","slug":"invalid-lane-lane-expected-one-of-vali","errorCode":null,"errorMessage":"Invalid lane '${lane}'. Expected one of ${[...VALID_LANES].join(', ')}.","messagePattern":"Invalid lane '(.+?)'\\. Expected one of (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/control-pane/work-item-mutations.js","lineNumber":97,"sourceCode":"    status: status ?? 'running',\n    metadata,\n    updatedAt: new Date().toISOString()\n  });\n  return { claimed: true, item };\n}\n\n/**\n * Move a work item to a kanban lane (ready | running | blocked | done).\n */\nfunction moveWorkItem(store, { id, lane } = {}) {\n  if (!id) {\n    throw new Error('move requires a work item id.');\n  }\n  const laneKey = String(lane || '')\n    .trim()\n    .toLowerCase();\n  if (!VALID_LANES.has(laneKey)) {\n    throw new Error(`Invalid lane '${lane}'. Expected one of ${[...VALID_LANES].join(', ')}.`);\n  }\n  const target = store.getWorkItemById(id);\n  if (!target) {\n    throw new Error(`Work item not found: ${id}`);\n  }\n  const item = store.upsertWorkItem({\n    ...target,\n    status: LANE_TO_STATUS[laneKey],\n    updatedAt: new Date().toISOString()\n  });\n  return { moved: true, item };\n}\n\nmodule.exports = {\n  DONE_STATUSES,\n  LANE_TO_STATUS,\n  VALID_LANES,\n  VALID_ASSIGNEE_KINDS,","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/control-pane/work-item-mutations.js#L79-L115","documentation":"Thrown by moveWorkItem when lane, after trim+lowercase, is not in VALID_LANES (ready, running, blocked, done). The board renders exactly four lanes and maps each to a canonical status via LANE_TO_STATUS; any other lane name has no status mapping and would leave the item in an inconsistent state. Case and surrounding whitespace are tolerated by the normalization.","triggerScenarios":"Passing lane: 'in-progress' (should be 'running'); lane: 'archive' or 'todo'; a typo like 'runing'; passing a raw status string like 'blocked ' which trims fine, versus 'block' which fails.","commonSituations":"External system uses different lane names than the board; user-typed lane in a CLI; stale config referencing a renamed lane; confusing lane names with statuses ('open' is a status, 'ready' is the lane).","solutions":["Use one of: ready, running, blocked, done (case-insensitive, whitespace-trimmed).","Map your caller's lane vocabulary to the board's lanes before calling moveWorkItem.","Expose VALID_LANES from work-item-mutations.js and validate against it at the call site.","If a new lane is genuinely needed, add it to LANE_TO_STATUS (and update the board UI) — do not invent lane names ad hoc."],"exampleFix":"// before\nmoveWorkItem(store, { id, lane: 'in-progress' });\n\n// after — map to a valid lane\nconst LANE_ALIASES = { 'in-progress':'running', 'todo':'ready', 'complete':'done' };\nconst lane = LANE_ALIASES[String(rawLane).toLowerCase()] || rawLane;\nmoveWorkItem(store, { id, lane });","handlingStrategy":"type-guard","validationCode":"const VALID = new Set(['ready','running','blocked','done']);\nconst lane = String(rawLane || '').trim().toLowerCase();\nif (!VALID.has(lane)) {\n  throw new Error(`Invalid lane '${rawLane}'. Use one of: ${[...VALID].join(', ')}`);\n}","typeGuard":"function isValidLane(lane) {\n  const VALID = new Set(['ready','running','blocked','done']);\n  return VALID.has(String(lane || '').trim().toLowerCase());\n}","tryCatchPattern":"try {\n  moveWorkItem(store, { id, lane });\n} catch (e) {\n  if (/Invalid lane/.test(e.message)) { showLanePicker(); return; }\n  throw e;\n}","preventionTips":["Expose VALID_LANES from the module and validate against it.","Map external lane vocabularies to the four board lanes.","Use a dropdown constrained to valid lanes in the UI."],"tags":["work-items","move","validation","enum"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}