{"record":{"id":"a9b6d7944727c895","repo":"nanocoai/nanoclaw","slug":"handler-error","errorCode":"handler-error","errorMessage":"session not found: ${req.args.id}","messagePattern":"session not found: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/dispatch.ts","lineNumber":112,"sourceCode":"      if (req.args.help !== true && (req.command === 'wirings-get' || req.command === 'wirings-update')) {\n        const wiring = await getMessagingGroupAgentByPair(ctx.messagingGroupId, ctx.agentGroupId);\n        if (!wiring) return err(req.id, 'forbidden', 'Wiring not found for this conversation.');\n        fill.id = wiring.id;\n      }\n      req = { ...req, args: { ...req.args, ...fill } };\n\n      // Fail-closed pre-handler check for sessions-get/-history: returns\n      // \"not found\" regardless of whether the UUID exists in another group,\n      // preventing an existence oracle across group boundaries. (history\n      // also self-scopes in its handler — this is defense-in-depth.)\n      if (\n        cmd.resource === 'sessions' &&\n        (req.command === 'sessions-get' || req.command === 'sessions-history') &&\n        req.args.id\n      ) {\n        const s = await getSession(req.args.id as string);\n        if (!s || s.agent_group_id !== ctx.agentGroupId) {\n          return err(req.id, 'handler-error', `session not found: ${req.args.id}`);\n        }\n      }\n    }\n  }\n\n  const decision = await guard(commandGuard(cmd.name), {\n    actor: actorFor(ctx),\n    payload: req.args,\n    grant: opts.grant ?? null,\n  });\n\n  if (decision.effect === 'deny') {\n    return err(req.id, 'forbidden', decision.reason);\n  }\n\n  // `--help` interception: answer with the command's generated help instead of\n  // executing. Placed after the guard's deny (a group-scoped agent can't probe\n  // forbidden resources) and BEFORE hold execution — asking for help on an","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/cli/dispatch.ts#L94-L130","documentation":"A group-scoped agent asked for `sessions-get` or `sessions-history` with a session id that either doesn't exist or belongs to a different agent group. The check is fail-closed: both cases return the same 'session not found' so agents can't probe UUIDs that exist in other groups.","triggerScenarios":"Agent passes a session id from another group, a malformed/truncated UUID, or a stale id from a deleted session; also when copy-pasting an id out of `ncl sessions list` output of a different group.","commonSituations":"Agent hallucinates or truncates a UUID; session was cleaned up by the sweep; operator scoped the agent to `group` while the agent assumed global visibility.","solutions":["List this group's own sessions: `ncl sessions list` (auto-scoped) and use one of those ids","Check the id is a complete UUID with no whitespace/quotes","If cross-group access is genuinely needed, an operator sets `ncl groups config update --cli-scope global` (approval-gated) or runs it host-side"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const sessions = await runNcl('sessions list --json'); // auto-scoped to own group\nconst ok = sessions.some(s => s.id === targetId);\nif (!ok) throw new Error('session id not in this group');","typeGuard":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nfunction isUuid(v: unknown): v is string { return typeof v === 'string' && UUID_RE.test(v); }","tryCatchPattern":"Treat 'session not found' as terminal for that id — don't retry with variations; re-list sessions instead.","preventionTips":["Always source session ids from this group's own `sessions list` output","Validate UUID shape before sending","Don't assume global visibility under cli_scope group"],"tags":["cli","ncl","sessions","forbidden","group-scope"],"backgroundTag":"resource-not-found-or-forbidden","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}