Fix routing default to only apply in single-assistant mode#6261
Conversation
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: remove assistantId dependency from Telegram attachment delivery (#6210) Co-authored-by: Claude <noreply@anthropic.com> * feat: add Telegram webhook lifecycle reconciliation (#6211) Co-authored-by: Claude <noreply@anthropic.com> * feat: auto-configure gateway routing for single-assistant mode and add rejection visibility (#6212) Co-authored-by: Claude <noreply@anthropic.com> * feat: add Telegram Bot messaging provider for proactive outbound sends (#6222) Co-authored-by: Claude <noreply@anthropic.com> * feat: harden /deliver/telegram auth and align docs with Telegram capabilities (#6238) Co-authored-by: Claude <noreply@anthropic.com> * fix: correct misleading comment in Telegram attachment download path (#6241) Co-authored-by: Claude <noreply@anthropic.com> * fix: bound rejection notice cache with periodic eviction (#6242) Co-authored-by: Claude <noreply@anthropic.com> * fix: support tokenless providers in withProviderToken and fix testConnection error handling (#6244) Co-authored-by: Claude <noreply@anthropic.com> * fix: always reconcile webhook and normalize ingress URL (#6245) Co-authored-by: Claude <noreply@anthropic.com> * fix: resolve gateway lint error and credential security allowlist for Telegram adapter (#6257) Co-authored-by: Claude <noreply@anthropic.com> * fix: require webhook_secret in Telegram isConnected check (#6259) Co-authored-by: Claude <noreply@anthropic.com> * fix: only default routing policy in single-assistant deployments (#6261) Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
| const assistants = loadAllAssistants(); | ||
| const isSingleAssistant = assistants.length === 1; |
There was a problem hiding this comment.
🔴 Off-by-one in assistant count: loadAllAssistants() is called before saveAssistantEntry(), so the count is always stale
In the hatch flow, startGateway() is called at cli/src/commands/hatch.ts:531 before saveAssistantEntry() at cli/src/commands/hatch.ts:544. This means loadAllAssistants() at cli/src/lib/local.ts:294 reads the lockfile before the current assistant is registered, making the count off by one.
Detailed Explanation & Impact
This creates two concrete problems:
First hatch (fresh workspace): loadAllAssistants() returns [] (empty), so isSingleAssistant is false (0 ≠ 1). Neither GATEWAY_UNMAPPED_POLICY nor GATEWAY_DEFAULT_ASSISTANT_ID is set. The gateway defaults to reject policy (gateway/src/config.ts:108). This is a regression — the old code always set GATEWAY_UNMAPPED_POLICY=default, so Telegram messages would be routed. Now, a first-time user hatching a single assistant will find that Telegram messages are rejected.
Second hatch (one existing assistant): loadAllAssistants() returns [first_assistant], so isSingleAssistant is true. The gateway starts with default policy pointing to the first assistant. But there are actually two assistants now (the second is about to be saved at line 544). This is exactly the multi-assistant misrouting scenario the PR is trying to prevent.
The fix should either move saveAssistantEntry() before startGateway(), or pass the about-to-be-saved entry into the count logic so it accounts for the new assistant.
Prompt for agents
The root cause is that startGateway() at cli/src/lib/local.ts:294 calls loadAllAssistants() to count assistants, but in the hatch flow (cli/src/commands/hatch.ts:531), startGateway() is called BEFORE saveAssistantEntry() at line 544. This means the count is always off by one.
To fix this, in cli/src/commands/hatch.ts function hatchLocal(), move the saveAssistantEntry() call (currently at line 543-544) to before the startGateway() call (line 531). You will need to construct the localEntry object earlier (before startGateway), using a placeholder for runtimeUrl, then update runtimeUrl after startGateway returns. Alternatively, you could change startGateway() to accept an optional parameter indicating how many additional assistants are about to be added, but moving saveAssistantEntry earlier is cleaner.
Was this helpful? React with 👍 or 👎 to provide feedback.
Codex P1 feedback on #6247: startGateway() was unconditionally setting GATEWAY_UNMAPPED_POLICY=default which could route messages to the wrong assistant in multi-assistant workspaces. Now only applies when the workspace has exactly one assistant.