Skip to content

Conversation

@MikeeBuilds
Copy link
Collaborator

@MikeeBuilds MikeeBuilds commented Jan 5, 2026

Summary

Fixes #563 | Linear: ACS-108 - The PR review (and other GitHub features) were failing with 401 authentication_error: Invalid bearer token.

Root Cause

The getRunnerEnv() utility was missing the OAuth token from the Claude Profile Manager. It only included API profile env vars (ANTHROPIC_*) for custom endpoints, but not the CLAUDE_CODE_OAUTH_TOKEN needed for default Claude OAuth authentication.

The OAuth token is stored encrypted in Electron's profile storage (macOS Keychain via safeStorage API), not as a system environment variable. The getProfileEnv() function retrieves and decrypts it.

Changes

Added getProfileEnv() call to runner-env.ts to include the decrypted OAuth token in the environment passed to Python subprocesses.

Environment Variable Precedence (lowest to highest):

  1. apiProfileEnv - Custom Anthropic-compatible API profile
  2. oauthModeClearVars - Clears stale ANTHROPIC_* vars when in OAuth mode
  3. profileEnv - Claude OAuth token from profile manager (NEW)
  4. extraEnv - Caller-specific vars (e.g., USE_CLAUDE_MD)

Impact

This fixes authentication for all GitHub features that use getRunnerEnv():

  • PR Review
  • Autofix
  • Triage

Testing

  • Build passes
  • Auth token correctly passed to subprocess environment

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved OAuth token handling and environment variable precedence for more reliable authentication configuration.
  • Documentation

    • Enhanced documentation clarifying environment variable priority and secure token sourcing.

✏️ Tip: You can customize this high-level summary in your review settings.

…dyMik90#563)

The getRunnerEnv utility was missing the OAuth token from the Claude
Profile Manager. It only included API profile env vars (ANTHROPIC_*)
for custom endpoints, but not the CLAUDE_CODE_OAUTH_TOKEN needed for
default Claude authentication.

Root cause: The OAuth token is stored encrypted in Electron's profile
storage (macOS Keychain via safeStorage), not as a system env var.
The getProfileEnv() function retrieves and decrypts it.

This fixes the 401 authentication errors in PR review, autofix,
and triage handlers that all use getRunnerEnv().
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 5, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

This change adds profile-based environment variables to the runner environment, specifically including the decrypted CLAUDE_CODE_OAUTH_TOKEN from secure storage. The profileEnv is merged with defined precedence to ensure the OAuth token is available in subprocess execution contexts.

Changes

Cohort / File(s) Summary
Profile Environment Integration
apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts
Added getProfileEnv() import and integrated profile environment variables into runner environment with precedence ordering. Updated documentation to clarify OAuth token sourcing from secure storage and environment variable merge hierarchy.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

  • Refresh Token Doesn't Work #563: This PR directly addresses the expired OAuth token issue by ensuring the decrypted CLAUDE_CODE_OAUTH_TOKEN from the active profile is properly included in subprocess environment variables.

Possibly related PRs

Suggested labels

bug, area/frontend, size/M, priority/high

Suggested reviewers

  • AndyMik90
  • AlexMadera

Poem

🐰 A token once lost in the expiring night,
Now springs forth from storage, secure and tight!
With precedence ordered and profiles aligned,
OAuth renewal, no more time confined! ✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: passing OAuth token to Python runner subprocesses to fix issue #563.
Linked Issues check ✅ Passed The PR addresses issue #563 by ensuring the OAuth token is included in the environment passed to Python subprocesses, directly fixing the authentication error.
Out of Scope Changes check ✅ Passed All changes are focused on resolving the OAuth token authentication issue; no out-of-scope modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @MikeeBuilds, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request rectifies a critical authentication issue affecting GitHub integration features such as PR review and autofix. By ensuring the Claude OAuth token is correctly retrieved from the profile manager and passed to Python subprocesses, it eliminates 401 authentication_error messages, restoring the intended functionality of these features.

Highlights

  • Authentication Fix: Resolves 401 authentication_error: Invalid bearer token in GitHub features (PR Review, Autofix, Triage) by ensuring the OAuth token is passed to Python subprocesses.
  • Root Cause Addressed: The getRunnerEnv() utility was previously missing the CLAUDE_CODE_OAUTH_TOKEN from the Claude Profile Manager, which is crucial for OAuth authentication.
  • Implementation: Integrates getProfileEnv() into runner-env.ts to retrieve and include the decrypted OAuth token in the environment variables provided to Python subprocesses.
  • Environment Variable Precedence: Updates the environment variable merging logic to correctly prioritize the Claude OAuth token (profileEnv) among other environment variables.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively resolves the authentication error by ensuring the Claude OAuth token is passed to Python subprocesses. The change is clear, well-documented with a helpful JSDoc comment explaining environment variable precedence, and directly addresses the root cause described in issue #563. I have one suggestion regarding code organization to improve long-term maintainability.

@@ -1,15 +1,31 @@
import { getOAuthModeClearVars } from '../../../agent/env-utils';
import { getAPIProfileEnv } from '../../../services/profile';
import { getProfileEnv } from '../../../rate-limit-detector';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For better code organization and maintainability, the getProfileEnv function seems misplaced in rate-limit-detector.ts. Its purpose is to retrieve profile-specific environment variables, which is more aligned with profile management than rate limit detection.

Consider moving getProfileEnv to a more logical location, such as ../../../services/profile, where the related getAPIProfileEnv function is already defined. This would improve code structure, make the function easier to find, and avoid creating a dependency on rate-limit-detector for a non-rate-limiting concern.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Fix all issues with AI Agents 🤖
In @apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts:
- Line 3: The import getProfileEnv from '../../../rate-limit-detector' indicates
the rate-limit-detector module now contains profile environment logic; extract
profile-related functions (e.g., getProfileEnv) into a dedicated module (suggest
name: profile-env or profile-utils), export them from that new module, update
runner-env.ts to import getProfileEnv from the new module, and update any other
files that currently import profile helpers from rate-limit-detector to the new
path; ensure exports/exports names remain consistent and run tests/typechecks to
confirm no breaking imports.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3930b12 and bdd270c.

📒 Files selected for processing (1)
  • apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts
🧰 Additional context used
📓 Path-based instructions (3)
apps/frontend/src/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings

Files:

  • apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts
apps/frontend/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use useTranslation() hook with namespace prefixes (e.g., 'navigation:items.key') for accessing translation strings in React components

Files:

  • apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts
apps/frontend/**/*.{ts,tsx}

⚙️ CodeRabbit configuration file

apps/frontend/**/*.{ts,tsx}: Review React patterns and TypeScript type safety.
Check for proper state management and component composition.

Files:

  • apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts
🧬 Code graph analysis (1)
apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts (1)
apps/frontend/src/main/agent/env-utils.ts (1)
  • getOAuthModeClearVars (22-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: CodeQL (python)
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (3)
apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts (3)

5-17: Excellent documentation of environment precedence and security details.

The expanded documentation clearly describes the environment variable precedence and the critical role of profileEnv in OAuth authentication. The reference to the encrypted storage mechanism (macOS Keychain via Electron's safeStorage API) is valuable context for maintainers.


25-30: Environment variable precedence is correctly implemented.

The spread order correctly implements the documented precedence, ensuring:

  • profileEnv includes the OAuth token after oauthModeClearVars (so it's not cleared)
  • extraEnv has the highest precedence for caller-specific overrides
  • The fix for #563 is properly integrated

23-23: No action needed. The getProfileEnv() function in apps/frontend/src/main/rate-limit-detector.ts already implements robust error handling:

  • Returns an empty object {} when no profile exists (line 266-268)
  • Safely handles token decryption failures with fallback logic (lines 274-278)
  • Provides fallback returns for default profiles and legacy configs
  • Always returns Record<string, string>, never null or undefined

The synchronous call on line 23 is safe and appropriate.

Likely an incorrect or invalid review comment.

@@ -1,15 +1,31 @@
import { getOAuthModeClearVars } from '../../../agent/env-utils';
import { getAPIProfileEnv } from '../../../services/profile';
import { getProfileEnv } from '../../../rate-limit-detector';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the rate-limit-detector module and getProfileEnv export

# Find the rate-limit-detector file
echo "=== Locating rate-limit-detector module ==="
fd -e ts -e tsx "rate-limit-detector" apps/frontend/src/main

# Navigate from the current file to check the relative path
echo -e "\n=== Checking relative path resolution ==="
# From apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts
# ../../../rate-limit-detector should resolve to apps/frontend/src/main/rate-limit-detector

# Check for files in the main directory
echo "Files in apps/frontend/src/main directory:"
ls -la apps/frontend/src/main/ | head -20

Repository: AndyMik90/Auto-Claude

Length of output: 1540


🏁 Script executed:

#!/bin/bash
# Check for getProfileEnv export in the module

echo "=== Checking for getProfileEnv exports ==="
rg -n "export.*getProfileEnv" apps/frontend/src/main

echo -e "\n=== Checking rate-limit-detector module content ==="
# Check all files named rate-limit-detector or containing the module
fd "rate-limit-detector" apps/frontend/src/main --type f -x cat -n {}

Repository: AndyMik90/Auto-Claude

Length of output: 37620


🏁 Script executed:

#!/bin/bash
# Examine the full content of the runner-env.ts file to understand context

echo "=== Full content of runner-env.ts ==="
cat -n apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts

Repository: AndyMik90/Auto-Claude

Length of output: 1591


Import path is correct; consider refactoring module organization.

The import path '../../../rate-limit-detector' resolves correctly. However, the module's scope has expanded beyond rate limiting to include profile environment management. If this module continues to grow, consider extracting profile-related functions into a dedicated module to improve clarity and maintainability.

🤖 Prompt for AI Agents
In @apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts around line
3, The import getProfileEnv from '../../../rate-limit-detector' indicates the
rate-limit-detector module now contains profile environment logic; extract
profile-related functions (e.g., getProfileEnv) into a dedicated module (suggest
name: profile-env or profile-utils), export them from that new module, update
runner-env.ts to import getProfileEnv from the new module, and update any other
files that currently import profile helpers from rate-limit-detector to the new
path; ensure exports/exports names remain consistent and run tests/typechecks to
confirm no breaking imports.

@MikeeBuilds MikeeBuilds added bug Something isn't working area/frontend This is frontend only size/S Small (10-99 lines) priority/high Important, fix this week labels Jan 5, 2026
@AndyMik90 AndyMik90 self-assigned this Jan 5, 2026
Copy link
Owner

@AndyMik90 AndyMik90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Auto Claude Review - APPROVED

Status: Ready to Merge

Summary: ### Merge Verdict: ✅ READY TO MERGE
No blocking issues. 1 non-blocking suggestion(s) to consider

Risk Assessment

Factor Level Notes
Complexity Low Based on lines changed
Security Impact None Based on security findings
Scope Coherence Good Based on structural review

Findings Summary

  • Low: 1 issue(s)

Generated by Auto Claude PR Review


💡 Suggestions (1)

These are non-blocking suggestions for consideration:

🔵 [LOW] Missing test coverage for new getProfileEnv integration

📁 apps/frontend/src/main/ipc-handlers/github/utils/runner-env.ts:0

The PR adds getProfileEnv() to the environment variable chain, but the existing test file (runner-env.test.ts) doesn't mock getProfileEnv and therefore doesn't test the new OAuth token functionality. While the implementation is correct, adding test coverage would improve confidence in the fix.

Suggested fix:

Add test case that mocks getProfileEnv to verify CLAUDE_CODE_OAUTH_TOKEN is properly included in the returned environment variables.

This automated review found no blocking issues. The PR can be safely merged.

Generated by Auto Claude

@AndyMik90 AndyMik90 merged commit 97f3449 into AndyMik90:develop Jan 5, 2026
14 checks passed
ruinosus added a commit to ruinosus/Auto-Claude that referenced this pull request Jan 6, 2026
Merged commits:
- fix: WIndows not finding the gith bash path (AndyMik90#724)
- fix(profiles): support API profiles in auth check and model resolution (AndyMik90#608)
- Fix Window Size on Hi-DPI Displays (AndyMik90#696)
- fix: centralize Claude CLI invocation (AndyMik90#680)
- fix(github): pass OAuth token to Python runner subprocesses (AndyMik90#698)
- chore: Update Linux app icon to use multiple resolution sizes (AndyMik90#672)
- fix(a11y): Add missing ARIA attributes for screen reader accessibility (AndyMik90#634)

Resolved conflicts in:
- apps/backend/core/auth.py (kept both Azure Foundry support + Windows git-bash detection)
- apps/frontend/src/main/agent/agent-queue.ts (kept Azure Foundry model resolution)
- apps/frontend/src/main/terminal/claude-integration-handler.ts (merged CLI invocation + Azure Foundry support)
- apps/frontend/src/renderer/components/ProjectTabBar.tsx (kept overflow menu + added aria-label)
- apps/frontend/src/shared/i18n/locales/en/common.json (merged all translation keys)
- apps/frontend/src/shared/i18n/locales/fr/common.json (merged all translation keys)
1nk1 pushed a commit to 1nk1/Auto-Claude that referenced this pull request Jan 8, 2026
…dyMik90#563) (AndyMik90#698)

The getRunnerEnv utility was missing the OAuth token from the Claude
Profile Manager. It only included API profile env vars (ANTHROPIC_*)
for custom endpoints, but not the CLAUDE_CODE_OAUTH_TOKEN needed for
default Claude authentication.

Root cause: The OAuth token is stored encrypted in Electron's profile
storage (macOS Keychain via safeStorage), not as a system env var.
The getProfileEnv() function retrieves and decrypts it.

This fixes the 401 authentication errors in PR review, autofix,
and triage handlers that all use getRunnerEnv().

Co-authored-by: Andy <[email protected]>
1nk1 pushed a commit to 1nk1/Auto-Claude that referenced this pull request Jan 8, 2026
…dyMik90#563) (AndyMik90#698)

The getRunnerEnv utility was missing the OAuth token from the Claude
Profile Manager. It only included API profile env vars (ANTHROPIC_*)
for custom endpoints, but not the CLAUDE_CODE_OAUTH_TOKEN needed for
default Claude authentication.

Root cause: The OAuth token is stored encrypted in Electron's profile
storage (macOS Keychain via safeStorage), not as a system env var.
The getProfileEnv() function retrieves and decrypts it.

This fixes the 401 authentication errors in PR review, autofix,
and triage handlers that all use getRunnerEnv().

Co-authored-by: Andy <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/frontend This is frontend only bug Something isn't working priority/high Important, fix this week size/S Small (10-99 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refresh Token Doesn't Work

2 participants