{"record":{"id":"3bedebd07bed7972","repo":"nanocoai/nanoclaw","slug":"from-and-to-must-differ-self-messages-are-nev","errorCode":null,"errorMessage":"--from and --to must differ (self-messages are never gated)","messagePattern":"--from and --to must differ \\(self-messages are never gated\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/resources/policies.ts","lineNumber":35,"sourceCode":"      type: 'string',\n      description: 'User-id who approves each gated message (required). Only this user (or an owner) can approve.',\n    },\n    { name: 'created_at', type: 'string', description: 'Auto-set.' },\n  ],\n  operations: { list: 'open' },\n  customOperations: {\n    set: {\n      access: 'approval',\n      description:\n        '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.',\n      handler: async (args) => {\n        const from = args.from as string;\n        const to = args.to as string;\n        const approver = args.approver as string;\n        if (!from) throw new Error('--from is required');\n        if (!to) throw new Error('--to is required');\n        if (!approver) throw new Error('--approver is required');\n        if (from === to) throw new Error('--from and --to must differ (self-messages are never gated)');\n        if (!(await getAgentGroup(from))) throw new Error(`source agent group not found: ${from}`);\n        if (!(await getAgentGroup(to))) throw new Error(`target agent group not found: ${to}`);\n\n        await setMessagePolicy(from, to, approver, new Date().toISOString());\n        return { from_agent_group_id: from, to_agent_group_id: to, approver };\n      },\n    },\n    remove: {\n      access: 'approval',\n      description: 'Remove an approval policy (back to free flow). Use --from <agent-group-id> --to <agent-group-id>.',\n      handler: async (args) => {\n        const from = args.from as string;\n        const to = args.to as string;\n        if (!from) throw new Error('--from is required');\n        if (!to) throw new Error('--to is required');\n        if (!(await removeMessagePolicy(from, to))) throw new Error('policy not found');\n        return { removed: { from_agent_group_id: from, to_agent_group_id: to } };\n      },","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/cli/resources/policies.ts#L17-L53","documentation":"Thrown by `ncl policies set` when --from and --to reference the same agent group. Self-messages within one group are never routed through the inter-agent gating path, so a self-policy would be meaningless and is rejected up front.","triggerScenarios":"Passing the same group id to both flags — usually a copy-paste of one id into both slots, or a script that fills both from one variable.","commonSituations":"Operator intends to gate a group's outbound messages to a different group but reuses the same id; automation loops that accidentally set from === to.","solutions":["Use two distinct group ids: re-check `ncl groups list` and pick the actual source and target","If you meant self-message gating, that is not supported by this command — remove the policy intent"],"exampleFix":"// before\nncl policies set --from grp-a --to grp-a --approver telegram:owner\n// after\nncl policies set --from grp-a --to grp-b --approver telegram:owner","handlingStrategy":"validation","validationCode":"if (from === to) throw new Error('from and to must differ');","typeGuard":"const isDistinctPair = (a, b) => Boolean(a && b && a !== b);","tryCatchPattern":null,"preventionTips":["Never derive both ids from the same variable","Self-gating is unsupported by design — don't attempt it"],"tags":["cli","invalid-argument","policies","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}