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

  1. Add --title when creating a new item: `upsert my-item --title "..."`.
  2. 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.
  3. 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

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


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