nanocoai/nanoclaw · error
forbidden
forbidden
Error message
Wiring not found for this conversation.
What it means
A group-scoped agent tried to get/update the wiring for a conversation its agent group is not actually wired to. The dispatcher resolves the wiring by the (messagingGroupId, agentGroupId) pair from the caller context — never from a caller-supplied ID — and returns `forbidden` when no such wiring exists. This is deliberate scope enforcement so an agent can't inspect or edit wirings of other groups.
Source
Thrown at src/cli/dispatch.ts:96
if (cliScope === 'group') {
// Auto-fill agent-group-related args so the agent doesn't need
// to pass its own group ID explicitly.
const fill: Record<string, unknown> = {
agent_group_id: req.args.agent_group_id ?? ctx.agentGroupId,
group: req.args.group ?? ctx.agentGroupId,
};
// Only auto-fill --id for resources where it IS the agent group ID
// (groups, destinations). For sessions/members --id is a different key.
if (cmd.resource === 'groups' || cmd.resource === 'destinations') {
fill.id = req.args.id ?? ctx.agentGroupId;
}
// Group-scoped agents may only inspect or update the wiring for the
// conversation they are currently serving. Never trust a caller ID.
if (req.args.help !== true && (req.command === 'wirings-get' || req.command === 'wirings-update')) {
const wiring = await getMessagingGroupAgentByPair(ctx.messagingGroupId, ctx.agentGroupId);
if (!wiring) return err(req.id, 'forbidden', 'Wiring not found for this conversation.');
fill.id = wiring.id;
}
req = { ...req, args: { ...req.args, ...fill } };
// Fail-closed pre-handler check for sessions-get/-history: returns
// "not found" regardless of whether the UUID exists in another group,
// preventing an existence oracle across group boundaries. (history
// also self-scopes in its handler — this is defense-in-depth.)
if (
cmd.resource === 'sessions' &&
(req.command === 'sessions-get' || req.command === 'sessions-history') &&
req.args.id
) {
const s = await getSession(req.args.id as string);
if (!s || s.agent_group_id !== ctx.agentGroupId) {
return err(req.id, 'handler-error', `session not found: ${req.args.id}`);
}
}View on GitHub (pinned to 294ef2aee8)
Solutions
- Verify the wiring still exists: `ncl wirings list` and look for the (messaging group, agent group) pair
- Re-wire the messaging group to this agent group if it was removed intentionally-typo'd away
- Restart/let the session re-resolve so the agent context reflects the current wiring
- For legitimate cross-group wiring inspection, an operator (not the agent) must run it host-side
Defensive patterns
Strategy: validation
Validate before calling
const wirings = await runNcl('wirings list --json');
const mine = wirings.find(w => w.messaging_group_id === ctx.messagingGroupId && w.agent_group_id === ctx.agentGroupId);
if (!mine) throw new Error('not wired — ask the operator to re-wire'); Type guard
function wiringExistsForPair(list: Array<{messaging_group_id: string; agent_group_id: string}>, mgId: string, agId: string): boolean {
return list.some(w => w.messaging_group_id === mgId && w.agent_group_id === agId);
} Try / catch
Match code === 'forbidden' for wirings-get/update and fall back to informing the user the chat isn't wired to this agent.
Prevention
- Treat wirings as operator-owned state; verify wiring exists before offering wirings commands to agents
- Re-check wiring after any rewire or migration
- Don't cache wiring ids across sessions
When it happens
Trigger: An agent in `cli_scope: group` sends `wirings-get`/`wirings-update` while serving a session whose messaging group was unwired from this agent group, or after rewiring the chat to a different agent group.
Common situations: Operator rewired the channel to another group while the agent session was live; the session was created under an old wiring and is now orphaned; agent replaying an old command with a stale wiring id.
Related errors
- handler-error
- Provide --apt <pkg> or --npm <pkg>
- Provide --host <host-path> and --container <container-path>
- messaging group not found: ${id}
- --threads must be true or false, got "${v}"
AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28).
Data as JSON: /api/errors/ecab66e5a1e8d3d2.
Report an issue: GitHub.