affaan-m/ECC · error · Error
assigneeKind must be 'agent' or 'human'.
Error message
assigneeKind must be 'agent' or 'human'.
What it means
claimWorkItem accepts an optional assigneeKind that must be 'agent' or 'human' (case-insensitive). Any other non-empty value throws "assigneeKind must be 'agent' or 'human'." This is an enum whitelist check before the store write.
Solutions
- Use exactly 'agent' or 'human' (any casing — it is lowercased before the check).
- Remove the assigneeKind argument entirely if you don't need the distinction; it is optional.
- Map your tool/role names to the allowed kinds before calling: bot/orchestrator → 'agent', person → 'human'.
- Check VALID_ASSIGNEE_KINDS in work-item-mutations.js if the allowed set changes in a newer version.
Example fix
// before
claimWorkItem(store, { id, owner: 'alice', assigneeKind: 'bot' });
// after
claimWorkItem(store, { id, owner: 'alice', assigneeKind: 'agent' }); Defensive patterns
Strategy: validation
Validate before calling
const VALID = new Set(['agent', 'human']);
const kind = assigneeKind ? String(assigneeKind).toLowerCase() : null;
if (kind && !VALID.has(kind)) throw new Error(`assigneeKind must be agent|human, got ${assigneeKind}`); Type guard
function isValidAssigneeKind(k) { return k == null || ['agent', 'human'].includes(String(k).toLowerCase()); } Try / catch
try { claimWorkItem(store, { id, owner, assigneeKind }); } catch (e) {
if (e.message.includes("assigneeKind must be")) return claimWorkItem(store, { id, owner });
throw e;
} Prevention
- Only pass 'agent' or 'human'; map tool/role names before the call.
- Omit assigneeKind when the distinction is unnecessary.
- Keep a shared constant for allowed kinds instead of inline strings.
- Re-check VALID_ASSIGNEE_KINDS after library upgrades.
When it happens
Trigger: claimWorkItem(store, { id, owner, assigneeKind: 'bot' }) or assigneeKind: 'AI' with unexpected casing/wording; passing a role name ('reviewer') instead of the allowed kinds.
Common situations: Automation passing its tool name as assigneeKind; CLI flag typos (--assignee-knd); older scripts written before the assigneeKind option existed using freeform strings.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid lane ' '. Expected one of .
- artifact has invalid modality binding
- claim requires an owner.
- CV effect has an invalid subject anchor
- explicit candidate review state required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/19e8196a3ac3f197.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/control-pane/work-item-mutations.js:62
}
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,
owner,
sessionId: sessionId ?? target.sessionId ?? null,
status: status ?? 'running',
metadata,View on GitHub (pinned to 8321021c54)