Bug: `/remote-control` intermittently unavailable — `tengu_ccr_bridge` flag flips to `false` after background GrowthBook cache refresh

Resolved 💬 2 comments Opened Mar 14, 2026 by neoman007-git Closed Mar 14, 2026

Environment

| Field | Value |
|---|---|
| Plan | Max (20x), stripe_subscription |
| hasExtraUsageEnabled | true |
| hasAvailableSubscription | false (see §4 — assessed as red herring) |
| Platform | macOS |
| CC Version | Latest (2.1.76) |

---

Observed Behaviour

Reliable reproduction sequence:

  1. /logout inside CC + logout of Claude Desktop + pkill -f claude
  2. claude login/remote-control is available, tengu_ccr_bridge: true in ~/.claude.json
  3. After some interval (next session or background refresh), /remote-control disappears
  4. Inspection of ~/.claude.json shows tengu_ccr_bridge: false in cachedGrowthBookFeatures

Failure modes:

  • /remote-control → "Unknown skill: remote-control" (command hidden)
  • claude remote-control → "Remote Control is not yet enabled for your account"

The flag state is the single consistent differentiator between working and broken states.

---

Code Path (from decompiled cli.js)

function isBridgeEnabled() {
  return getFeatureFlag("tengu_ccr_bridge", false);
}

function isRemoteControlEnabled() {
  return isBridgeEnabled() && isPolicyAllowed("allow_remote_sessions");
}

/remote-control command visibility is gated entirely on isBridgeEnabled(). Default is false — so any failure to fetch or evaluate the GrowthBook flag results in RC being hidden. The allow_remote_sessions policy is not the constraint here (Max personal account, no org policy).

---

hasAvailableSubscription: false — Red Herring

~/.claude.json shows:

"hasAvailableSubscription": false,
"oauthAccount": {
  "hasExtraUsageEnabled": true,
  "billingType": "stripe_subscription"
}

The RC code path (isRemoteControlEnabled()) does not reference hasAvailableSubscription. Confirmed non-blocking: RC works immediately post-login despite this field being false throughout.

---

GrowthBook Cache Mechanism

CC caches GrowthBook feature flags in ~/.claude.json under cachedGrowthBookFeatures. This cache is:

  • Populated on login — fresh server evaluation returns tengu_ccr_bridge: true
  • Refreshed periodically in background — subsequent evaluation returns tengu_ccr_bridge: false
  • Not manually overridable — any manual edit to the cache file is overwritten on next startup/refresh

Note: heartbeat_interval_ms: 0 and session_keepalive_interval_ms: 0 appear in the bridge poll config — likely downstream symptoms of the flag being false, not an independent cause.

---

Differential Diagnosis

Hypothesis A: Staged Rollout

  • Against: Flag returns true immediately on fresh login for the same account. A pure staged rollout would return a consistent value regardless of login state.
  • Verdict: Unlikely

Hypothesis B: GrowthBook Cohort Assignment Keyed on Session/Device Identifier ← Most Probable

  • For: Fresh login produces new session context → new GrowthBook evaluation → true. Background refresh uses stale/different session context → false. Explains flag instability for the same account.
  • For: Consistent with issue #28583 where tengu_ccr_bridge was false on macOS but true on Ubuntu for the same account — different device = different cohort assignment.
  • Verdict: Most probable root cause

Hypothesis C: OAuth Token Refresh Drops Required Scope

  • For: Background token refresh has a known race condition across multiple CC sessions (issue #24317). A refreshed token without the required scope could cause server-side GrowthBook evaluation to return false.
  • Verdict: Plausible compounding factor, especially with multiple concurrent CC sessions

Hypothesis D: CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC / DISABLE_TELEMETRY

  • Confirmed absent from shell profile.
  • Verdict: Eliminated

---

Diagnostic Questions

  1. What attribute is GrowthBook using as the user identifier for tengu_ccr_bridge cohort assignment? If it is session ID, device ID, or OAuth token ID rather than account UUID, that is the direct cause of instability.
  1. Is tengu_ccr_bridge intended to be account-stable for Max subscribers? If yes, the cohort assignment logic has a bug. If no, it is in active A/B rollout and the login-cycle workaround is expected behaviour.
  1. Does server-side GrowthBook evaluation for cachedGrowthBookFeatures refresh take OAuth token scope into account? If so, a token refresh dropping user:sessions:claude_code would corrupt the cached flag on the next refresh cycle.
  1. What triggers cachedGrowthBookFeatures background refresh? Time-based TTL, session start, or API call? Understanding the trigger would allow isolation of exactly when the flag flips.

---

Related Issues

| Issue | Relevance |
|---|---|
| #28583 | Same flag false on macOS, true on Ubuntu — same account. Confirms device/session-keyed cohort assignment. |
| #33119 | CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC blocks GrowthBook entirely — separate cause, same symptom |
| #24317 | OAuth token refresh race condition across concurrent sessions — potential compounding factor |
| #29430 | Widespread regression: RC unavailable post re-auth for Max subscribers |
| #33580 | tengu_amber_quartz (voice flag) same pattern — cache overwritten on startup — confirms systemic GrowthBook cache instability |

---

Recommended Fix

Short-term: Pin GrowthBook cohort assignment for tengu_ccr_bridge to account UUID (or oauthAccount.id) rather than session/device identifier. This ensures the flag is stable across sessions, background refreshes, and re-authentications.

Medium-term: If the flag is in staged rollout, expose explicit eligibility feedback rather than silently defaulting to false — Max subscribers should not require a login cycle to access a plan-entitled feature.

Current workaround: claude logout && claude login — restores access until next background cachedGrowthBookFeatures refresh.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗