-
Notifications
You must be signed in to change notification settings - Fork 375
fix: Comprehensive authentication error handling #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,6 +36,47 @@ | |
| r'aws[_-]?secret[=:][^\s]+', | ||
| ] | ||
|
|
||
| # Patterns that indicate Claude CLI authentication errors | ||
| AUTH_ERROR_PATTERNS = [ | ||
| r"not\s+logged\s+in", | ||
| r"not\s+authenticated", | ||
| r"authentication\s+(failed|required|error)", | ||
| r"login\s+required", | ||
| r"please\s+(run\s+)?['\"]?claude\s+login", | ||
| r"unauthorized", | ||
| r"invalid\s+(token|credential|api.?key)", | ||
| r"expired\s+(token|session|credential)", | ||
| r"could\s+not\s+authenticate", | ||
| r"sign\s+in\s+(to|required)", | ||
| ] | ||
|
Comment on lines
+39
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: Summary — common Claude (Claude Code / claude CLI) authentication errors and what they mean
Quick checklist to fix auth problems
Sources
Would you like exact command examples for exporting keys, running /login, or checking your config file? 🏁 Script executed: # Find the is_auth_error function and understand pattern usage
rg -A 10 "is_auth_error|AUTH_ERROR_PATTERNS" server/services/process_manager.pyRepository: leonvanzyl/autocoder Length of output: 1944 🏁 Script executed: # Search for any test files that might show expected error messages
fd -e test.py -e spec.py -o -e "*test*.py" | xargs rg -l "AUTH_ERROR|auth.*error" 2>/dev/null | head -5Repository: leonvanzyl/autocoder Length of output: 241 🏁 Script executed: # Look for any claude CLI or authentication-related documentation in the repo
fd -type f \( -name "*.md" -o -name "*.txt" -o -name "*.rst" \) | xargs rg -l "claude.*login|authentication.*error|not.*logged" 2>/dev/null | head -10Repository: leonvanzyl/autocoder Length of output: 361 Add missing patterns for API key and setup-token errors. The patterns cover most common authentication errors well, but the web documentation reveals gaps:
These additions would ensure more comprehensive coverage of Claude CLI authentication error messages as documented. 🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| def is_auth_error(text: str) -> bool: | ||
| """Check if text contains Claude CLI authentication error messages.""" | ||
| if not text: | ||
| return False | ||
| text_lower = text.lower() | ||
| for pattern in AUTH_ERROR_PATTERNS: | ||
| if re.search(pattern, text_lower): | ||
| return True | ||
| return False | ||
|
|
||
|
|
||
| AUTH_ERROR_HELP = """ | ||
| ================================================================================ | ||
| AUTHENTICATION ERROR DETECTED | ||
| ================================================================================ | ||
|
|
||
| Claude CLI requires authentication to work. | ||
|
|
||
| To fix this, run: | ||
| claude login | ||
|
|
||
| This will open a browser window to sign in. | ||
| After logging in, try starting the agent again. | ||
| ================================================================================ | ||
| """ | ||
|
|
||
|
|
||
| def sanitize_output(line: str) -> str: | ||
| """Remove sensitive information from output lines.""" | ||
|
|
@@ -185,6 +226,9 @@ async def _stream_output(self) -> None: | |
| if not self.process or not self.process.stdout: | ||
| return | ||
|
|
||
| auth_error_detected = False | ||
| output_buffer = [] # Buffer recent lines for auth error detection | ||
|
|
||
| try: | ||
| loop = asyncio.get_running_loop() | ||
| while True: | ||
|
|
@@ -198,6 +242,18 @@ async def _stream_output(self) -> None: | |
| decoded = line.decode("utf-8", errors="replace").rstrip() | ||
| sanitized = sanitize_output(decoded) | ||
|
|
||
| # Buffer recent output for auth error detection | ||
| output_buffer.append(decoded) | ||
| if len(output_buffer) > 20: | ||
| output_buffer.pop(0) | ||
|
|
||
| # Check for auth errors | ||
| if not auth_error_detected and is_auth_error(decoded): | ||
| auth_error_detected = True | ||
| # Broadcast auth error help message | ||
| for help_line in AUTH_ERROR_HELP.strip().split('\n'): | ||
| await self._broadcast_output(help_line) | ||
|
|
||
| await self._broadcast_output(sanitized) | ||
|
|
||
| except asyncio.CancelledError: | ||
|
|
@@ -209,6 +265,12 @@ async def _stream_output(self) -> None: | |
| if self.process and self.process.poll() is not None: | ||
| exit_code = self.process.returncode | ||
| if exit_code != 0 and self.status == "running": | ||
| # Check buffered output for auth errors if we haven't detected one yet | ||
| if not auth_error_detected: | ||
| combined_output = '\n'.join(output_buffer) | ||
| if is_auth_error(combined_output): | ||
| for help_line in AUTH_ERROR_HELP.strip().split('\n'): | ||
| await self._broadcast_output(help_line) | ||
| self.status = "crashed" | ||
| elif self.status == "running": | ||
| self.status = "stopped" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,40 +20,18 @@ fi | |
|
|
||
| echo "[OK] Claude CLI found" | ||
|
|
||
| # Check if user has credentials | ||
| CLAUDE_CREDS="$HOME/.claude/.credentials.json" | ||
| if [ -f "$CLAUDE_CREDS" ]; then | ||
| echo "[OK] Claude credentials found" | ||
| # Note: Claude CLI no longer stores credentials in ~/.claude/.credentials.json | ||
| # We can't reliably check auth status without making an API call, so we just | ||
| # verify the CLI is installed and remind the user to login if needed | ||
| if [ -d "$HOME/.claude" ]; then | ||
| echo "[OK] Claude CLI directory found" | ||
| echo " (If you're not logged in, run: claude login)" | ||
|
Comment on lines
+23
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implementation doesn't match PR description: missing CLI operational check. The PR description explicitly states the fix should use: if claude --version &> /dev/null && [ -d "$HOME/.claude" ]; thenHowever, line 26 only checks for the directory: if [ -d "$HOME/.claude" ]; thenThe 🔧 Add the operational check as described in the PR-if [ -d "$HOME/.claude" ]; then
+if claude --version &> /dev/null && [ -d "$HOME/.claude" ]; then
echo "[OK] Claude CLI directory found"
echo " (If you're not logged in, run: claude login)"🤖 Prompt for AI Agents |
||
| else | ||
| echo "[!] Not authenticated with Claude" | ||
| echo "[!] Claude CLI not configured" | ||
| echo "" | ||
| echo "You need to run 'claude login' to authenticate." | ||
| echo "This will open a browser window to sign in." | ||
| echo "Please run 'claude login' to authenticate before continuing." | ||
| echo "" | ||
| read -p "Would you like to run 'claude login' now? (y/n): " LOGIN_CHOICE | ||
|
|
||
| if [[ "$LOGIN_CHOICE" =~ ^[Yy]$ ]]; then | ||
| echo "" | ||
| echo "Running 'claude login'..." | ||
| echo "Complete the login in your browser, then return here." | ||
| echo "" | ||
| claude login | ||
|
|
||
| # Check if login succeeded | ||
| if [ -f "$CLAUDE_CREDS" ]; then | ||
| echo "" | ||
| echo "[OK] Login successful!" | ||
| else | ||
| echo "" | ||
| echo "[ERROR] Login failed or was cancelled." | ||
| echo "Please try again." | ||
| exit 1 | ||
| fi | ||
| else | ||
| echo "" | ||
| echo "Please run 'claude login' manually, then try again." | ||
| exit 1 | ||
| fi | ||
| read -p "Press Enter to continue anyway, or Ctrl+C to exit..." | ||
| fi | ||
|
Comment on lines
29
to
35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Script still blocks execution, contradicting PR's non-blocking claim. The PR description states the change "emits a non-blocking warning with instructions when not configured (instead of forcing login)" and "removes the forced interactive flow." However, line 34 still blocks execution: read -p "Press Enter to continue anyway, or Ctrl+C to exit..."This forces user interaction before the script can proceed, which contradicts the non-blocking design goal. ♻️ Make the warning truly non-blocking else
echo "[!] Claude CLI not configured"
echo ""
echo "Please run 'claude login' to authenticate before continuing."
- echo ""
- read -p "Press Enter to continue anyway, or Ctrl+C to exit..."
fi🤖 Prompt for AI Agents |
||
|
|
||
| echo "" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Claude CLI ~/.claude directory authentication configuration💡 Result:
Summary — what ~/.claude is and how authentication/config works
~/.claude contains Claude Code user settings (settings.json) and per-project .claude/settings*.json files. User settings apply globally; project settings live in .claude/ in the project. [1][2]
Authentication is normally done with an Anthropic API key via the ANTHROPIC_API_KEY environment variable. Claude Code also supports enterprise providers (Amazon Bedrock, Google Vertex) by setting provider-specific env vars and credentials (e.g., CLAUDE_CODE_USE_BEDROCK=1 + AWS creds). Some third‑party wrappers/proxies (e.g., ZenMux) use different env vars (ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN). [3][2][5]
Quick examples
Notes / gotchas
Sources
[1] Claude Code settings (settings.json, user & project settings).
[2] Claude Code CLI reference (commands/flags & config file locations).
[3] Claude Code SDK — Authentication (ANTHROPIC_API_KEY, Bedrock/Vertex).
[4] Community config reference (example ~/.claude config).
[5] Third‑party integration note (env loading / ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN).
The directory-based authentication check is unreliable and should verify the ANTHROPIC_API_KEY environment variable instead.
Web search confirms that Claude CLI authentication is primarily handled via the
ANTHROPIC_API_KEYenvironment variable (or provider-specific env vars for enterprise), not by checking directory existence. While~/.claudestores settings.json, the directory's presence does not reliably indicate authentication is configured—a user could have the directory without credentials set, or vice versa.Instead, the check should verify the relevant environment variable(s):
ANTHROPIC_API_KEYis setCLAUDE_CODE_USE_BEDROCK,CLAUDE_CODE_USE_VERTEX, or similar provider flags alongside their respective credentials🤖 Prompt for AI Agents