affaan-m/ECC · error · Error
Missing work item id. Pass <id> or --id <id>.
Error message
Missing work item id. Pass <id> or --id <id>.
What it means
Thrown by buildUpsertPayload() when resolveWorkItemId(options) returns null, i.e. neither options.id nor options.positionals[0] is set (resolveWorkItemId at line 133-135). Every upsert needs a stable local id because the SQLite store keys work items on it; upsert with no id cannot decide between insert and update.
Source
Thrown at scripts/work-items.js:320
);
}
const closedItems = closeStaleGithubItems(store, repo, activeIds, { limit: Math.max(limit * 4, 1000) });
return {
repo,
syncedAt,
prCount: prs.length,
issueCount: issues.length,
closedCount: closedItems.length,
items,
closedItems
};
}
function buildUpsertPayload(options, existing = null) {
const id = resolveWorkItemId(options);
if (!id) {
throw new Error('Missing work item id. Pass <id> or --id <id>.');
}
const title = options.title ?? (existing && existing.title);
if (!title) {
throw new Error('Missing --title for a new work item.');
}
return {
id,
source: options.source ?? (existing && existing.source) ?? 'manual',
sourceId: options.sourceId ?? (existing && existing.sourceId) ?? null,
title,
status: options.status ?? (existing && existing.status) ?? 'open',
priority: options.priority ?? (existing && existing.priority) ?? null,
url: options.url ?? (existing && existing.url) ?? null,
owner: options.owner ?? (existing && existing.owner) ?? null,
repoRoot: options.repoRoot ?? (existing && existing.repoRoot) ?? process.cwd(),
sessionId: options.sessionId ?? (existing && existing.sessionId) ?? null,View on GitHub (pinned to 01e15490f0)
Solutions
- Supply an id positionally: `node scripts/work-items.js upsert my-item --title "My item"`.
- Or use --id: `node scripts/work-items.js upsert --id my-item --title "My item"`.
- If importing from a source system, derive a stable id like `github-<owner-name-repo>-pr-<n>` so re-runs update rather than duplicate.
Example fix
// before node scripts/work-items.js upsert --title "Refactor state store" // after node scripts/work-items.js upsert refactor-state-store --title "Refactor state store"
Defensive patterns
Strategy: validation
Validate before calling
function ensureUpsertId(options) {
const id = options.id || (options.positionals && options.positionals[0]);
if (!id) throw new Error('upsert needs <id> or --id <id>');
options.id = id;
return options;
}
// call before buildUpsertPayload(ensureUpsertId(options), existing) Type guard
function hasWorkItemId(options) {
return Boolean(options && (options.id || (options.positionals && options.positionals[0])));
} Prevention
- Always pass an explicit, stable local id on upsert (derive one from the source system).
- In scripts, resolve and set options.id before calling buildUpsertPayload.
- Use a deterministic id scheme so re-runs update rather than duplicate.
When it happens
Trigger: Calling the 'upsert' command with no positional id and no --id flag, e.g. `node scripts/work-items.js upsert --title "x"`. Also triggered when calling buildUpsertPayload() directly without setting options.id or options.positionals. The 'close' command does its own id check first (error 487) so it does not reach this path.
Common situations: Assuming the title or source-id is enough to identify the item; forgetting that upsert requires an explicit local id (it is not auto-generated); migrating a script that previously used only --source-id.
Related errors
- Missing --title for a new work item.
- Missing work item id.
- Missing issue number.
- Missing --repo <owner/repo>.
- Missing GitHub repo. Pass --repo <owner/repo>.
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/1266826417872301.
Report an issue: GitHub.