nanocoai/nanoclaw · error · Error

--approver is required

Error message

--approver is required

What it means

Thrown by `ncl policies set` when the --approver flag is missing. Every agent-to-agent approval policy names a specific approver user who (alongside owners) can approve gated messages, so the field is mandatory.

Source

Thrown at src/cli/resources/policies.ts:34

      name: 'approver',
      type: 'string',
      description: 'User-id who approves each gated message (required). Only this user (or an owner) can approve.',
    },
    { name: 'created_at', type: 'string', description: 'Auto-set.' },
  ],
  operations: { list: 'open' },
  customOperations: {
    set: {
      access: 'approval',
      description:
        'Require approval for messages from one agent to another. Use --from <agent-group-id> --to <agent-group-id> --approver <user-id>. Only the named approver (or an owner) can approve.',
      handler: async (args) => {
        const from = args.from as string;
        const to = args.to as string;
        const approver = args.approver as string;
        if (!from) throw new Error('--from is required');
        if (!to) throw new Error('--to is required');
        if (!approver) throw new Error('--approver is required');
        if (from === to) throw new Error('--from and --to must differ (self-messages are never gated)');
        if (!(await getAgentGroup(from))) throw new Error(`source agent group not found: ${from}`);
        if (!(await getAgentGroup(to))) throw new Error(`target agent group not found: ${to}`);

        await setMessagePolicy(from, to, approver, new Date().toISOString());
        return { from_agent_group_id: from, to_agent_group_id: to, approver };
      },
    },
    remove: {
      access: 'approval',
      description: 'Remove an approval policy (back to free flow). Use --from <agent-group-id> --to <agent-group-id>.',
      handler: async (args) => {
        const from = args.from as string;
        const to = args.to as string;
        if (!from) throw new Error('--from is required');
        if (!to) throw new Error('--to is required');
        if (!(await removeMessagePolicy(from, to))) throw new Error('policy not found');
        return { removed: { from_agent_group_id: from, to_agent_group_id: to } };

View on GitHub (pinned to 294ef2aee8)

Solutions

  1. Pass --approver with a user id: `ncl policies set --from <a> --to <b> --approver telegram:owner`
  2. Confirm the user id exists via `ncl users list`

Example fix

// before
ncl policies set --from grp-a --to grp-b
// after
ncl policies set --from grp-a --to grp-b --approver telegram:owner
Defensive patterns

Strategy: validation

Validate before calling

if (!approver || !approver.includes(':')) throw new Error('--approver must be a user id <channel>:<handle>');

Type guard

const isUserId = (s) => /^[a-z0-9-]+:[A-Za-z0-9_.-]+$/.test(s);

Prevention

When it happens

Trigger: Running `ncl policies set --from <a> --to <b>` without --approver; assuming approval falls back to any admin automatically.

Common situations: Operator expects the default approver resolution (pickApprover) to apply here — it does not; the CLI policy path requires an explicit approver id.

Related errors


AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28). Data as JSON: /api/errors/52107062ce26378f. Report an issue: GitHub.