nexu-io/open-design · error

proposal summary is required

Error message

proposal summary is required

What it means

Thrown by createAutomationProposal() when input.summary is missing or whitespace-only. summary is required because it is the human-readable rationale shown in the review UI and stored on the proposal record.

Source

Thrown at apps/daemon/src/automation-proposals.ts:82

): Promise<AutomationEvolutionProposal | null> {
  const proposals = await listAutomationProposals(dataDir, { status: 'all' });
  return proposals.find((proposal) => proposal.id === id) ?? null;
}

export async function createAutomationProposal(
  dataDir: string,
  input: CreateAutomationEvolutionProposalRequest & {
    id?: string;
    status?: AutomationProposalStatus;
  },
): Promise<AutomationEvolutionProposal> {
  const now = new Date().toISOString();
  if (!input || typeof input !== 'object') throw new Error('proposal body is required');
  if (typeof input.title !== 'string' || !input.title.trim()) {
    throw new Error('proposal title is required');
  }
  if (typeof input.summary !== 'string' || !input.summary.trim()) {
    throw new Error('proposal summary is required');
  }
  if (!input.patch || typeof input.patch !== 'object') {
    throw new Error('proposal patch is required');
  }
  const status =
    input.status && VALID_STATUSES.has(input.status)
      ? input.status
      : 'pending-review';
  const proposal: AutomationEvolutionProposal = {
    id:
      typeof input.id === 'string' && input.id.trim()
        ? input.id.trim()
        : `proposal_${randomUUID()}`,
    title: input.title.trim(),
    summary: input.summary.trim(),
    targetKind: input.targetKind,
    action: input.action,
    status,

View on GitHub (pinned to 5be4028344)

Solutions

  1. Provide a non-empty summary string describing why the proposal exists.
  2. For ingested sources, reuse the auto-generated 'Create a memory-tree entry from ...' summary shape.
  3. Validate summary.trim() on the client before submitting.

Example fix

// before
await createAutomationProposal(dataDir, { title: 'T', summary: '', patch: { format: 'json', after: '{}' } });
// after
await createAutomationProposal(dataDir, { title: 'T', summary: 'Captures pricing feedback from the sales channel.', patch: { format: 'json', after: '{}' } });
Defensive patterns

Strategy: validation

Validate before calling

if (typeof input.summary !== 'string' || !input.summary.trim()) {
  throw new Error('proposal summary is required');
}

Type guard

function hasNonEmptySummary(value: unknown): value is string {
  return typeof value === 'string' && value.trim().length > 0;
}

Prevention

When it happens

Trigger: POST to the proposals endpoint with summary omitted, empty, whitespace-only, or non-string. Fires after the title check and before the patch check.

Common situations: Agent submitted a proposal with only a title; client form dropped the summary field; reviewer-facing rationale was left for later and never filled.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/8879639c7de173f9. Report an issue: GitHub.