affaan-m/ECC · error · Error

claim requires an owner.

Error message

claim requires an owner.

What it means

claimWorkItem requires an owner (agent or human name) to record who is taking the item. With no owner supplied it throws 'claim requires an owner.' rather than guessing an identity. This is a precondition guard before any store mutation.

Solutions

  1. Pass owner explicitly: claimWorkItem(store, { id, owner: 'agent-name' }).
  2. For CLI, supply the owner flag (e.g. --owner agent-name).
  3. In the control pane, enter a non-empty name when prompted; the prompt result must be non-null/non-empty.
  4. Set a default agent identity in your automation config so owner is always populated.

Example fix

// before
claimWorkItem(store, { id });
// after
claimWorkItem(store, { id, owner: process.env.AGENT_NAME || 'human-operator' });
Defensive patterns

Strategy: validation

Validate before calling

if (!owner || typeof owner !== 'string' || !owner.trim()) {
  throw new Error('Refusing to claim: owner is required.');
}

Type guard

function hasOwner(args) { return typeof args?.owner === 'string' && args.owner.trim().length > 0; }

Try / catch

try { claimWorkItem(store, { id, owner }); } catch (e) {
  if (e.message === 'claim requires an owner.') { owner = promptForOwner(); return claimWorkItem(store, { id, owner }); }
  throw e;
}

Prevention

When it happens

Trigger: claimWorkItem(store, { id }) or claimWorkItemCli(...) with owner undefined/null/empty string — omitted CLI flag, empty prompt input in the control pane, or a config not passing agent identity.

Common situations: Running the claim CLI without --owner; user cancels or submits empty text at the window.prompt in eccClaimItem; automation scripts that never set an agent name env/config.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/9ab1c9aee89d9fe9. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/control-pane/work-item-mutations.js:58

  if (id) {
    const item = store.getWorkItemById(id);
    if (!item) {
      throw new Error(`Work item not found: ${id}`);
    }
    return item;
  }
  const { items } = store.listWorkItems({ limit: 100 });
  return items.filter(item => !item.owner && isOpenStatus(item.status)).sort((a, b) => priorityRank(a.priority) - priorityRank(b.priority))[0] || null;
}

/**
 * Claim an unassigned work item for an agent or human. Sets the owner (and
 * optional assigneeKind) and moves the card to running unless an explicit
 * status is supplied. Returns { claimed, item } or { claimed: false, reason }.
 */
function claimWorkItem(store, { id, owner, assigneeKind, sessionId, status } = {}) {
  if (!owner) {
    throw new Error('claim requires an owner.');
  }
  const kind = assigneeKind ? String(assigneeKind).toLowerCase() : null;
  if (kind && !VALID_ASSIGNEE_KINDS.has(kind)) {
    throw new Error("assigneeKind must be 'agent' or 'human'.");
  }
  const target = selectClaimTarget(store, { id });
  if (!target) {
    return { claimed: false, reason: 'no-unassigned-open-items' };
  }
  if (!isOpenStatus(target.status)) {
    throw new Error(`Work item ${target.id} is already done; cannot claim.`);
  }
  const metadata = { ...(target.metadata || {}) };
  if (kind) {
    metadata.assigneeKind = kind;
  }
  const item = store.upsertWorkItem({
    ...target,

View on GitHub (pinned to 8321021c54)