affaan-m/ECC · error · Error
Missing --title for a new work item.
Error message
Missing --title for a new work item.
What it means
Thrown by buildUpsertPayload() when a title cannot be resolved. The title comes from options.title or, only when updating an existing item, existing.title. So a brand-new item (existing is null) with no --title has nothing to store and is rejected. This is intentionally separate from the id check so the error message points at the actually missing field.
Source
Thrown at scripts/work-items.js:325
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,
metadata: options.metadataJson !== undefined ? parseMetadataJson(options.metadataJson) : ((existing && existing.metadata) ?? null),
createdAt: existing ? existing.createdAt : undefined,
updatedAt: new Date().toISOString()
};
}View on GitHub (pinned to 01e15490f0)
Solutions
- Add --title when creating a new item: `upsert my-item --title "..."`.
- If you intended to update an existing item, first verify the id exists with `show <id>`; a typo in the id makes existing null and forces this error.
- When scripting idempotent creates, always pass --title so the first run (insert) and later runs (update) both succeed.
Example fix
// before node scripts/work-items.js upsert 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 ensureUpsertTitle(options, existing) {
const title = options.title || (existing && existing.title);
if (!title) throw new Error('upsert of a new item needs --title');
return title;
}
// call: ensureUpsertTitle(options, store.getWorkItemById(id)) Type guard
function hasUpsertTitle(options, existing) {
return Boolean(options && (options.title || (existing && existing.title)));
} Prevention
- Always pass --title when creating; only omit it when you know the item exists.
- Before upserting, run `show <id>` to confirm existence if you plan to rely on the stored title.
- Make CI idempotent by always passing both --id and --title.
When it happens
Trigger: Creating a new work item without --title: `node scripts/work-items.js upsert my-item` with no title flag and no existing item for that id. Note that when an item already exists, the missing flag is tolerated and the stored title is reused.
Common situations: Running upsert to 'just set status' on an id you expect to exist but does not (so existing is null and there is no title fallback); copying a close-style invocation into upsert; CI job that sets --status but forgets --title on first run.
Related errors
- Missing work item id. Pass <id> or --id <id>.
- Missing issue number.
- Missing --repo <owner/repo>.
- Missing GitHub repo. Pass --repo <owner/repo>.
- claim requires --owner <name>.
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/89ac686d348f7eea.
Report an issue: GitHub.