← Back to PRs

#23039: fix: subagent announce fails with pairing required due to missing operator.write scope

by ascott open 2026-02-21 23:27 View on GitHub →
agents size: XS
## Problem When a sub-agent completes, `runSubagentAnnounceFlow` calls `callGateway()` for methods like `agent`, `send`, `chat.history`, etc. Without explicit scopes, `callGateway` resolves to least-privilege scopes per method (e.g., `operator.write` for `agent`). If the device identity was originally paired with `[operator.admin, operator.approvals, operator.pairing]` but not `operator.write`, the gateway detects a scope-upgrade and rejects with "pairing required" (code 1008). ## Fix Explicitly pass `ANNOUNCE_SCOPES` (`[operator.admin, operator.read, operator.write]`) to all `callGateway` calls in `src/agents/subagent-announce.ts`. This ensures the announce flow — which is an internal process running on the same machine — requests all needed scopes upfront rather than relying on least-privilege resolution that may trigger scope-upgrade rejection. ## Changes - Added `ANNOUNCE_SCOPES` constant with admin + read + write scopes - Added `scopes: ANNOUNCE_SCOPES` to all 7 `callGateway` calls in the announce flow - No behavioral change for devices that already have all scopes paired <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds explicit scope declarations (`ANNOUNCE_SCOPES = [operator.admin, operator.read, operator.write]`) to all 7 `callGateway` calls in the subagent announce flow. This prevents "pairing required" errors when device identity was paired without `operator.write` scope, since the announce flow previously relied on least-privilege scope resolution that would trigger scope-upgrade rejection. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with no risk - The fix is narrowly scoped to a single file, addresses a specific authentication issue with a well-documented solution, and all modified `callGateway` calls legitimately require the scopes being requested. The approach of explicitly passing scopes for internal operations is sound and follows security best practices. - No files require special attention <sub>Last reviewed commit: 49b20a6</sub> <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs