affaan-m/ECC · error · Error

Work item not found: ${id}

Error message

Work item not found: ${id}

What it means

Thrown by selectClaimTarget (work-item-mutations.js) when claimWorkItem is called with an explicit id that does not resolve through store.getWorkItemById. The JIT board cannot claim a card it cannot find; unlike the no-id path (which returns { claimed:false, reason }), an explicit-but-missing id is treated as a caller bug and throws.

Source

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

    String(status || '')
      .trim()
      .toLowerCase()
  );
}

function priorityRank(priority) {
  return PRIORITY_RANK[String(priority || '').toLowerCase()] ?? 2;
}

/**
 * Resolve which work item a claim targets: an explicit id, otherwise the
 * highest-priority unassigned open item (the JIT pickup queue).
 */
function selectClaimTarget(store, { id } = {}) {
  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)) {

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Refresh the work-item list (store.listWorkItems) and retry claim with a current id.
  2. Strip and validate the id before calling (id && typeof id === 'string' && !id.includes(' ')).
  3. To pick up the next available item instead, omit id entirely and let selectClaimTarget use the priority queue.
  4. Wrap claim in try/catch and treat this error as a recoverable 'retry after refresh' rather than fatal.

Example fix

// before
claimWorkItem(store, { id: rawId, owner });

// after — verify the id exists first, else fall back to JIT pickup
const target = rawId ? store.getWorkItemById(rawId) : null;
if (rawId && !target) {
  console.warn(`id ${rawId} gone; falling back to JIT queue`);
}
claimWorkItem(store, { id: target ? target.id : undefined, owner });
Defensive patterns

Strategy: validation

Validate before calling

if (id && !store.getWorkItemById(id)) {
  throw new Error(`Cannot claim: work item ${id} does not exist (refresh and retry)`);
}

Type guard

function itemExists(store, id) {
  return Boolean(id && store.getWorkItemById(id));
}

Try / catch

try {
  claimWorkItem(store, { id, owner });
} catch (e) {
  if (/Work item not found/.test(e.message)) { await load(); return; }
  throw e;
}

Prevention

When it happens

Trigger: Calling claimWorkItem({ id, owner }) where id was deleted, never existed, belongs to a different store/workspace, or is stale from a cached list; passing an id with wrong casing or whitespace; race where another worker deleted the item between list and claim.

Common situations: A stale UI/CLI list references an id that was since closed; copy-paste of an id from one workspace into another; trailing whitespace/newline in an id read from stdin or a file; concurrent agent deleted the item.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/7196281a4783c3cb. Report an issue: GitHub.