{"record":{"id":"9ab1c9aee89d9fe9","repo":"affaan-m/ECC","slug":"claim-requires-an-owner","errorCode":null,"errorMessage":"claim requires an owner.","messagePattern":"claim requires an owner\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/control-pane/work-item-mutations.js","lineNumber":58,"sourceCode":"  if (id) {\n    const item = store.getWorkItemById(id);\n    if (!item) {\n      throw new Error(`Work item not found: ${id}`);\n    }\n    return item;\n  }\n  const { items } = store.listWorkItems({ limit: 100 });\n  return items.filter(item => !item.owner && isOpenStatus(item.status)).sort((a, b) => priorityRank(a.priority) - priorityRank(b.priority))[0] || null;\n}\n\n/**\n * Claim an unassigned work item for an agent or human. Sets the owner (and\n * optional assigneeKind) and moves the card to running unless an explicit\n * status is supplied. Returns { claimed, item } or { claimed: false, reason }.\n */\nfunction claimWorkItem(store, { id, owner, assigneeKind, sessionId, status } = {}) {\n  if (!owner) {\n    throw new Error('claim requires an owner.');\n  }\n  const kind = assigneeKind ? String(assigneeKind).toLowerCase() : null;\n  if (kind && !VALID_ASSIGNEE_KINDS.has(kind)) {\n    throw new Error(\"assigneeKind must be 'agent' or 'human'.\");\n  }\n  const target = selectClaimTarget(store, { id });\n  if (!target) {\n    return { claimed: false, reason: 'no-unassigned-open-items' };\n  }\n  if (!isOpenStatus(target.status)) {\n    throw new Error(`Work item ${target.id} is already done; cannot claim.`);\n  }\n  const metadata = { ...(target.metadata || {}) };\n  if (kind) {\n    metadata.assigneeKind = kind;\n  }\n  const item = store.upsertWorkItem({\n    ...target,","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/control-pane/work-item-mutations.js#L40-L76","documentation":"Thrown by claimWorkItem when the owner argument is falsy (undefined, null, empty string). Every claim must attribute the item to an owner (agent name or human name) so the board and audit trail stay accurate; an ownerless claim would leave the card assigned to nobody. This is a precondition failure, not a state problem.","triggerScenarios":"Calling claimWorkItem({ owner: '' }) or claimWorkItem({ id }) with no owner; a UI prompt (window.prompt) that returned null/empty when the user cancelled or left it blank; a CLI flag --owner that was not passed.","commonSituations":"User pressed Cancel/Enter on the 'Claim as' prompt (eccClaimItem in ui.js returns early on falsy owner but other callers may not); CLI invocation missing the --owner argument; agent loop forgot to pass its session identity.","solutions":["Always pass a non-empty owner string (agent id or human name) when calling claimWorkItem.","In UI/CLI code, validate owner before calling and show a helpful message if empty rather than letting the throw propagate.","For agent callers, derive owner from the session/agent identity so it can never be empty.","Add a unit test asserting claimWorkItem throws on empty owner to lock the contract."],"exampleFix":"// before\nclaimWorkItem(store, { id, owner: name });\n\n// after — guard at the call site\nif (!owner || !owner.trim()) {\n  throw new Error('Please provide a non-empty owner name to claim.');\n}\nclaimWorkItem(store, { id, owner: owner.trim() });","handlingStrategy":"validation","validationCode":"if (!owner || typeof owner !== 'string' || !owner.trim()) {\n  throw new Error('Claim requires a non-empty owner name.');\n}","typeGuard":"function isValidOwner(owner) {\n  return typeof owner === 'string' && owner.trim().length > 0;\n}","tryCatchPattern":"try {\n  claimWorkItem(store, { id, owner });\n} catch (e) {\n  if (/claim requires an owner/.test(e.message)) { promptForOwner(); return; }\n  throw e;\n}","preventionTips":["Validate owner at the UI/CLI boundary before calling claimWorkItem.","Derive owner from agent identity in automated callers.","Unit-test the empty-owner guard to lock the contract."],"tags":["work-items","claim","validation","precondition"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}