Skip to content

OAuth MCP: delete expired token row on 401 so users can re-auth - #2211

Merged
RoiGlinik merged 4 commits into
masterfrom
worktree-mcp-oauth-token-expiry
Jun 23, 2026
Merged

RoiGlinik merged 4 commits into
masterfrom
worktree-mcp-oauth-token-expiry

Conversation

@RoiGlinik

@RoiGlinik RoiGlinik commented Jun 22, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Fix OAuthToolConnector._evict_expired_token: was gated to DiskTokenStore (CLI only). In server mode (DalTokenStore), the expired Supabase row was never deleted → frontend kept rendering "Failed" with no clickable recovery path → user stuck.
  • Clear stale _user_tools[user][toolset] on the same 401 branch. Without this, apply_user_tools keeps substituting the now-dead tool list for the _connect placeholder, so the LLM keeps calling dead tools.

The old "another cluster may have refreshed in parallel" justification for the DAL gate doesn't survive scrutiny: by the time a 401 reaches _evict_expired_token, the background refresh loop has already failed against this stored token. The row is genuinely dead.

Test plan

  • New unit tests in tests/core/tools_utils/test_oauth_tool_connector_eviction.py — red on master, green with the fix:
    • test_401_deletes_token_in_both_stores[DalTokenStore] — confirms delete_token is now called for the DAL store
    • test_401_deletes_token_in_both_stores[DiskTokenStore] — confirms disk-store behaviour is preserved
    • test_401_clears_stale_user_tools — confirms _user_tools cleanup
  • Live verified on a real cluster against Atlassian's hosted MCP (https://mcp.atlassian.com/v1/mcp): forced expiry via Supabase, rolled patched image → eviction path fires → row deleted → FE flips "Failed" → "Login" → re-auth → 31 Atlassian tools rediscover → recovery loop closed.
  • All 121 adjacent OAuth tests still pass (tests/test_mcp_oauth.py tests/core/tools_utils/).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved OAuth authentication error handling for 401/403 failures by clearing expired tokens and removing any stale, per-user tools associated with the affected toolset. This prevents the app from substituting dead tools after an auth error, allowing the UI to recover cleanly and return to a fresh login state.

Previously _evict_expired_token only deleted from DiskTokenStore (CLI),
not DalTokenStore (server), so on 401 the Supabase row stayed and the
frontend kept showing "Failed" forever with no clickable recovery path.
The stale per-user tool list also remained, causing the LLM to keep
calling dead tools instead of falling back to the _connect placeholder.

Both branches now run on 401: delete the persisted token row regardless
of store, and clear _user_tools[user][toolset] so apply_user_tools
re-exposes the placeholder for fresh OAuth.

The justification for the original DAL gate (another cluster might have
refreshed in parallel) doesn't hold: by the time a 401 reaches here, the
background refresh loop has already failed; the stored token is dead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Roi Glinik <groi.tech@gmail.com>
@github-actions

github-actions Bot commented Jun 22, 2026 •

Copy link
Copy Markdown
Contributor

📂 Previous Runs

⚠️ 1 older run truncated

Older runs were omitted to stay under GitHub's 64KB comment size limit.


✅ Results of HolmesGPT evals

Automatically triggered by commit 535b6bf on branch worktree-mcp-oauth-token-expiry

View workflow logs

Results of HolmesGPT evals

  • ask_holmes: 14/14 test cases were successful, 0 regressions
Status Test case Time Turns Tools Cost Total tokens Input Max input Output Max output Cached Non-cached Reasoning Skill Generated Skills Read Compactions Denied commands Src
✅ 09_crashpod 26.2s 3 7 $0.2095 57,342 55,825 21,119 1,517 668 33,911 21,914 158 — — — — src
✅ 101_loki_historical_logs_pod_deleted 62.3s 5 11 $0.2971 102,850 99,456 23,184 3,394 1,221 75,777 23,679 771 — — — — src
✅ 112_find_pvcs_by_uuid 16.9s 2 2 $0.1737 37,666 36,711 20,165 955 517 16,543 20,168 293 — — — — src
✅ 12_job_crashing 30.2s 4 7 $0.2101 75,132 73,668 20,004 1,464 423 53,090 20,578 152 — — — — src
✅ 176_network_policy_blocking_traffic_no_skills 36.7s 5 9 $0.2364 97,701 96,085 21,446 1,616 412 73,944 22,141 198 — — — — src
✅ 227_count_configmaps_per_namespace[0] 20.0s 3 6 $0.1671 53,004 52,299 18,866 705 439 33,429 18,870 30 — — — — src
✅ 243_pod_names_contain_service 38.4s 3 7 $0.2074 56,533 54,867 20,205 1,666 659 33,889 20,978 283 — — — — src
✅ 24_misconfigured_pvc 35.0s 5 10 $0.2358 97,215 95,554 21,192 1,661 394 73,652 21,902 94 — — — — src
✅ ✍️ 254_elasticsearch_dr_test_log_check 73.0s 10 12 $0.3101 156,078 152,416 19,577 3,662 928 132,496 19,920 239 1 — — — src
✅ ✍️ 259_wrong_cluster_logs_confusion 84.0s 7 9 $0.2943 115,998 112,129 19,946 3,869 997 92,175 19,954 742 1 — — — src
✅ ✍️ 260_global_es_remote_cluster_logs 84.3s 11 13 $0.3515 180,250 175,998 21,068 4,252 914 154,011 21,987 657 1 — — — src
✅ 43_current_datetime_from_prompt 6.8s 1 — $0.1170 16,653 16,530 16,530 123 123 0 16,530 79 — — — — src
✅ 51_logs_summarize_errors 22.1s 3 2 $0.1768 53,711 52,809 19,431 902 539 33,374 19,435 33 — — — — src
✅ 61_exact_match_counting 12.1s 2 1 $0.1310 33,588 33,371 16,861 217 148 16,507 16,864 30 — — — — src
Total 39.1s avg 4.6 avg 7.4 avg $3.1176 1,133,721 1,107,718 23,184 26,003 1,221 822,798 284,920 3,759 3 — — —
Skills mechanism stats
  • Evals that emitted at least one memory: 3
  • Replays attempted: 0
  • Replays where the agent loaded the captured skill: 0/0
  • Replays that answered correctly: 0/0
  • Mean replay vs primary delta (per-row average): — cost, — tokens (n=0)
Benchmark Comparison Details

Master baseline: latest master-* experiment (post-merge regression eval)
Status: 14 test/model combinations loaded

Benchmark baseline: latest ci-benchmark experiment on master
Status: 257 test/model combinations loaded

Time comparison (seconds):

Test case This branch master (3d ago) Δ vs master benchmark (2d ago) Δ vs benchmark
09_crashpod (opus-4.6) 📄 26.2s 29.4s ↓11% 26.7s ±0%
101_loki_historical_logs_pod_deleted (opus-4.6) 📄 62.3s 46.4s ↑34% 636.1s ↓90%
112_find_pvcs_by_uuid (opus-4.6) 📄 16.9s 15.6s ±0% 13.1s ↑28%
12_job_crashing (opus-4.6) 📄 30.2s 25.1s ↑20% 24.4s ↑24%
176_network_policy_blocking_traffic_no_skills (opus-4.6) 📄 36.7s 32.4s ↑13% 31.9s ↑15%
227_count_configmaps_per_namespace[0] (opus-4.6) 📄 20.0s 14.5s ↑37% 14.5s ↑37%
243_pod_names_contain_service (opus-4.6) 📄 38.4s 29.0s ↑32% 27.5s ↑40%
24_misconfigured_pvc (opus-4.6) 📄 35.0s 30.6s ↑15% 27.5s ↑27%
254_elasticsearch_dr_test_log_check (opus-4.6) 📄 73.0s 68.8s ±0% 71.5s ±0%
259_wrong_cluster_logs_confusion (opus-4.6) 📄 84.0s 84.2s ±0% 68.0s ↑24%
260_global_es_remote_cluster_logs (opus-4.6) 📄 84.3s 77.8s ±0% 61.5s ↑37%
43_current_datetime_from_prompt (opus-4.6) 📄 6.8s 3.8s ↑79% 3.2s ↑113%
51_logs_summarize_errors (opus-4.6) 📄 22.1s 18.6s ↑19% 15.1s ↑47%
61_exact_match_counting (opus-4.6) 📄 12.1s 7.3s ↑64% 6.4s ↑88%
Total (all, n=14) 39.1s 34.5s — 73.4s —
Comparable (m=14, b=14) 39.1s 34.5s ↑13% 73.4s ↓47%

Cost comparison:

Test case This branch master (3d ago) Δ vs master benchmark (2d ago) Δ vs benchmark
09_crashpod (opus-4.6) 📄 $0.2095 $0.2304 ±0% $0.2309 ±0%
101_loki_historical_logs_pod_deleted (opus-4.6) 📄 $0.2971 $0.2757 ±0% $3.4626 ↓91%
112_find_pvcs_by_uuid (opus-4.6) 📄 $0.1737 $0.1732 ±0% $0.1728 ±0%
12_job_crashing (opus-4.6) 📄 $0.2101 $0.2092 ±0% $0.2117 ±0%
176_network_policy_blocking_traffic_no_skills (opus-4.6) 📄 $0.2364 $0.2539 ±0% $0.2740 ↓14%
227_count_configmaps_per_namespace[0] (opus-4.6) 📄 $0.1671 $0.1674 ±0% $0.1674 ±0%
243_pod_names_contain_service (opus-4.6) 📄 $0.2074 $0.1998 ±0% $0.2143 ±0%
24_misconfigured_pvc (opus-4.6) 📄 $0.2358 $0.2365 ±0% $0.2533 ±0%
254_elasticsearch_dr_test_log_check (opus-4.6) 📄 $0.3101 $0.3342 ±0% $0.3623 ↓14%
259_wrong_cluster_logs_confusion (opus-4.6) 📄 $0.2943 $0.3685 ↓20% $0.3328 ↓12%
260_global_es_remote_cluster_logs (opus-4.6) 📄 $0.3515 $0.3688 ±0% $0.3134 ↑12%
43_current_datetime_from_prompt (opus-4.6) 📄 $0.1170 $0.1170 ±0% $0.1171 ±0%
51_logs_summarize_errors (opus-4.6) 📄 $0.1768 $0.1730 ±0% $0.1725 ±0%
61_exact_match_counting (opus-4.6) 📄 $0.1310 $0.1310 ±0% $0.1310 ±0%
Total (all, n=14) $0.2227 $0.2313 — $0.4583 —
Comparable (m=14, b=14) $0.2227 $0.2313 ±0% $0.4583 ↓51%

Total tokens comparison:

Test case This branch master (3d ago) Δ vs master benchmark (2d ago) Δ vs benchmark
09_crashpod (opus-4.6) 📄 57,342 78,851 ↓27% 78,756 ↓27%
101_loki_historical_logs_pod_deleted (opus-4.6) 📄 102,850 101,178 ±0% 3,011,791 ↓97%
112_find_pvcs_by_uuid (opus-4.6) 📄 37,666 37,684 ±0% 37,638 ±0%
12_job_crashing (opus-4.6) 📄 75,132 75,000 ±0% 75,218 ±0%
176_network_policy_blocking_traffic_no_skills (opus-4.6) 📄 97,701 102,465 ±0% 105,366 ±0%
227_count_configmaps_per_namespace[0] (opus-4.6) 📄 53,004 53,013 ±0% 53,028 ±0%
243_pod_names_contain_service (opus-4.6) 📄 56,533 55,789 ±0% 57,318 ±0%
24_misconfigured_pvc (opus-4.6) 📄 97,215 97,234 ±0% 85,370 ↑14%
254_elasticsearch_dr_test_log_check (opus-4.6) 📄 156,078 166,485 ±0% 194,499 ↓20%
259_wrong_cluster_logs_confusion (opus-4.6) 📄 115,998 183,807 ↓37% 133,446 ↓13%
260_global_es_remote_cluster_logs (opus-4.6) 📄 180,250 186,227 ±0% 159,503 ↑13%
43_current_datetime_from_prompt (opus-4.6) 📄 16,653 16,651 ±0% 16,656 ±0%
51_logs_summarize_errors (opus-4.6) 📄 53,711 53,405 ±0% 53,519 ±0%
61_exact_match_counting (opus-4.6) 📄 33,588 33,592 ±0% 33,589 ±0%
Total (all, n=14) 80,980 88,670 — 292,550 —
Comparable (m=14, b=14) 80,980 88,670 ±0% 292,550 ↓72%

Cached tokens comparison:

Test case This branch master (3d ago) Δ vs master benchmark (2d ago) Δ vs benchmark
09_crashpod (opus-4.6) 📄 33,911 54,605 ↓38% 54,541 ↓38%
101_loki_historical_logs_pod_deleted (opus-4.6) 📄 75,777 75,268 ±0% 2,832,791 ↓97%
112_find_pvcs_by_uuid (opus-4.6) 📄 16,543 16,543 ±0% 16,543 ±0%
12_job_crashing (opus-4.6) 📄 53,090 53,078 ±0% 53,099 ±0%
176_network_policy_blocking_traffic_no_skills (opus-4.6) 📄 73,944 76,957 ±0% 77,290 ±0%
227_count_configmaps_per_namespace[0] (opus-4.6) 📄 33,429 33,434 ±0% 33,429 ±0%
243_pod_names_contain_service (opus-4.6) 📄 33,889 33,823 ±0% 34,060 ±0%
24_misconfigured_pvc (opus-4.6) 📄 73,652 73,495 ±0% 58,453 ↑26%
254_elasticsearch_dr_test_log_check (opus-4.6) 📄 132,496 141,125 ±0% 168,108 ↓21%
259_wrong_cluster_logs_confusion (opus-4.6) 📄 92,175 156,613 ↓41% 106,957 ↓14%
260_global_es_remote_cluster_logs (opus-4.6) 📄 154,011 158,508 ±0% 135,238 ↑14%
43_current_datetime_from_prompt (opus-4.6) 📄 — — — — —
51_logs_summarize_errors (opus-4.6) 📄 33,374 33,377 ±0% 33,380 ±0%
61_exact_match_counting (opus-4.6) 📄 16,507 16,507 ±0% 16,507 ±0%
Total (all, n=14) 58,771 65,952 — 258,600 —
Comparable (m=13, b=13) 63,292 71,026 ↓11% 278,492 ↓77%

Turns comparison:

Test case This branch master (3d ago) Δ vs master benchmark (2d ago) Δ vs benchmark
09_crashpod (opus-4.6) 📄 3 4 ↓25% 4 ↓25%
101_loki_historical_logs_pod_deleted (opus-4.6) 📄 5 5 ±0% 41 ↓88%
112_find_pvcs_by_uuid (opus-4.6) 📄 2 2 ±0% 2 ±0%
12_job_crashing (opus-4.6) 📄 4 4 ±0% 4 ±0%
176_network_policy_blocking_traffic_no_skills (opus-4.6) 📄 5 5 ±0% 5 ±0%
227_count_configmaps_per_namespace[0] (opus-4.6) 📄 3 3 ±0% 3 ±0%
243_pod_names_contain_service (opus-4.6) 📄 3 3 ±0% 3 ±0%
24_misconfigured_pvc (opus-4.6) 📄 5 5 ±0% 4 ↑25%
254_elasticsearch_dr_test_log_check (opus-4.6) 📄 10 10 ±0% 12 ↓17%
259_wrong_cluster_logs_confusion (opus-4.6) 📄 7 11 ↓36% 8 ↓12%
260_global_es_remote_cluster_logs (opus-4.6) 📄 11 11 ±0% 10 ↑10%
43_current_datetime_from_prompt (opus-4.6) 📄 1 1 ±0% 1 ±0%
51_logs_summarize_errors (opus-4.6) 📄 3 3 ±0% 3 ±0%
61_exact_match_counting (opus-4.6) 📄 2 2 ±0% 2 ±0%
Total (all, n=14) 4.6 4.9 — 7.3 —
Comparable (m=14, b=14) 4.6 4.9 ±0% 7.3 ↓37%

Tool calls comparison:

Test case This branch master (3d ago) Δ vs master benchmark (2d ago) Δ vs benchmark
09_crashpod (opus-4.6) 📄 7 8 ↓12% 8 ↓12%
101_loki_historical_logs_pod_deleted (opus-4.6) 📄 11 10 ↑10% 91 ↓88%
112_find_pvcs_by_uuid (opus-4.6) 📄 2 2 ±0% 2 ±0%
12_job_crashing (opus-4.6) 📄 7 7 ±0% 7 ±0%
176_network_policy_blocking_traffic_no_skills (opus-4.6) 📄 9 10 ↓10% 11 ↓18%
227_count_configmaps_per_namespace[0] (opus-4.6) 📄 6 6 ±0% 6 ±0%
243_pod_names_contain_service (opus-4.6) 📄 7 7 ±0% 8 ↓12%
24_misconfigured_pvc (opus-4.6) 📄 10 10 ±0% 9 ↑11%
254_elasticsearch_dr_test_log_check (opus-4.6) 📄 12 13 ±0% 15 ↓20%
259_wrong_cluster_logs_confusion (opus-4.6) 📄 9 13 ↓31% 11 ↓18%
260_global_es_remote_cluster_logs (opus-4.6) 📄 13 15 ↓13% 12 ±0%
43_current_datetime_from_prompt (opus-4.6) 📄 — — — — —
51_logs_summarize_errors (opus-4.6) 📄 2 2 ±0% 2 ±0%
61_exact_match_counting (opus-4.6) 📄 1 1 ±0% 1 ±0%
Total (all, n=14) 6.9 8.0 — 14.1 —
Comparable (m=13, b=13) 7.4 8.0 ±0% 14.1 ↓48%

Comparison indicators:

  • ±0% — diff under 10% (within noise threshold)
  • ↑N%/↓N% — diff 10-25%
  • ↑N%/↓N% — diff over 25% (significant)
📖 Legend
Icon Meaning
✅ The test was successful
➖ The test was skipped
⚠️ The test failed but is known to be flaky or known to fail
🚧 The test had a setup failure (not a code regression)
🔧 The test failed due to mock data issues (not a code regression)
🚫 The test was throttled by API rate limits/overload
❌ The test failed and should be fixed before merging the PR
🔄 Re-run evals manually

⚠️ Warning: /eval comments always run using the workflow from master, not from this PR branch. If you modified the GitHub Action (e.g., added secrets or env vars), those changes won't take effect.

To test workflow changes, use the GitHub CLI or Actions UI instead:

gh workflow run eval-regression.yaml --repo HolmesGPT/holmesgpt --ref worktree-mcp-oauth-token-expiry -f markers=regression -f filter=

Option 1: Comment on this PR with /eval:

/eval
tags: regression

Or with more options (one per line):

/eval
model: gpt-4o
tags: regression
id: 09_crashpod
iterations: 5

Run evals on a different branch (e.g., master) for comparison:

/eval
branch: master
tags: regression
Option Description
model Model(s) to test (default: same as automatic runs)
tags Pytest tags / markers (no default - runs all tests!)
id Eval ID / pytest -k filter (use /list to see valid eval names)
iterations Number of runs, max 10
branch Run evals on a different branch (for cross-branch comparison)

Quick re-run: Use /rerun to re-run the most recent /eval on this PR with the same parameters.

Option 2: Trigger via GitHub Actions UI → "Run workflow"

Option 3: Add PR labels to include extra evals (applies to both automatic runs and /eval comments):

Label Effect
evals-tag-<name> Run tests with tag <name> alongside regression
evals-id-<name> Run a specific eval by test ID
evals-model-<name> Override the model (use model list name, e.g. sonnet-4.5)

Examples: evals-tag-easy, evals-id-09_crashpod, evals-model-sonnet-4.5

🏷️ Valid tags

benchmark, chain-of-causation, compaction, confluence, context_window, conversation_worker, coralogix, counting, database, datadog, datetime, db-connectors, easy, elasticsearch, embeds, fable-not-opus, fast, frontend, grafana, hard, images, integration, kafka, kubernetes, leaked-information, logs, loki, manual, mcp, medium, metrics, multi-cluster, network, newrelic, no-cicd, numerical, one-test, port-forward, prometheus, question-answer, regression, skills, slackbot, storage, token-limit, toolset-limitation, traces, transparency, victorialogs

🤖 Valid models

deepseek-chat, deepseek-r1-reasoner, deepseek-reasoner, deepseek-v3.2-chat, fable-5, gemini-3-flash-preview, gemini-3-pro-preview, gemini-3.1-pro-preview, gpt-4.1, gpt-5.2-high-reasoning, gpt-5.3-codex, gpt-5.4, gpt-5.5, haiku-4.5, kimi-2.5, kimi-2.5-openrouter, opus-4.5, opus-4.6, opus-4.7, opus-4.8, qwen-next-80B-instruct, qwen-next-80B-thinking, sonnet-4.5, sonnet-4.6


Commands: /eval · /rerun · /list

CLI: gh workflow run eval-regression.yaml --repo HolmesGPT/holmesgpt --ref worktree-mcp-oauth-token-expiry -f markers=regression -f filter=

@coderabbitai

coderabbitai Bot commented Jun 22, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1217d570-21fd-4d67-9ab0-4061c6969550

📥 Commits

Reviewing files that changed from the base of the PR and between 01ad4f2 and a30d182.

📒 Files selected for processing (2)
  • holmes/core/tools_utils/oauth_tool_connector.py
  • tests/core/tools_utils/test_oauth_tool_connector_eviction.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • holmes/core/tools_utils/oauth_tool_connector.py

Walkthrough

OAuthToolConnector is updated so that a 401/403 during remote tool loading now clears stale per-user tool state via a new _clear_user_tools method, in addition to evicting the expired token. _evict_expired_token is updated to unconditionally delete the persisted token from any store type. A new test file adds regression coverage for both behaviors.

Changes

OAuth 401 Recovery Fix

Layer / File(s) Summary
Eviction and tool-cache clearing on auth error
holmes/core/tools_utils/oauth_tool_connector.py
Removes the DiskTokenStore-specific guard in _evict_expired_token so the persisted token is deleted from any backing store. Adds _clear_user_tools to remove stale entries from _user_tools and _user_tool_to_toolset. Extends the 401/403 branch in load_tools_for_user to call _clear_user_tools after token eviction. Removes the now-unused DiskTokenStore import.
Regression tests
tests/core/tools_utils/test_oauth_tool_connector_eviction.py
Adds module documentation of expected behavior, patched_manager fixture, _raise_401/_make_toolset helpers, a parametrized test asserting delete_token is called on both DalTokenStore and DiskTokenStore on 401, a test asserting _user_tools and _user_tool_to_toolset entries are cleared after 401, and a test asserting stale tool-name mappings are purged by tool name identity rather than toolset object identity.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main technical change: fixing OAuth token expiration handling by ensuring the expired token row is deleted from the database, enabling users to re-authenticate.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

@github-actions

github-actions Bot commented Jun 22, 2026 •

Copy link
Copy Markdown
Contributor

✅ Docker images ready for e3d603eca (built in 1m 9s)

⚠️ Warning: does not support ARM (ARM images are built on release only - not on every PR)

Use these tags to pull the images for testing.

📋 Copy commands

⚠️ Temporary images are deleted after 30 days. Copy to a permanent registry before using them:

gcloud auth configure-docker us-central1-docker.pkg.dev
docker pull us-central1-docker.pkg.dev/robusta-development/temporary-builds/holmes:e3d603eca
docker tag us-central1-docker.pkg.dev/robusta-development/temporary-builds/holmes:e3d603eca me-west1-docker.pkg.dev/robusta-development/development/holmes-dev:e3d603eca
docker push me-west1-docker.pkg.dev/robusta-development/development/holmes-dev:e3d603eca
docker pull us-central1-docker.pkg.dev/robusta-development/temporary-builds/holmes-operator:e3d603eca
docker tag us-central1-docker.pkg.dev/robusta-development/temporary-builds/holmes-operator:e3d603eca me-west1-docker.pkg.dev/robusta-development/development/holmes-operator-dev:e3d603eca
docker push me-west1-docker.pkg.dev/robusta-development/development/holmes-operator-dev:e3d603eca

Patch Helm values in one line (choose the chart you use):

HolmesGPT chart:

helm upgrade --install holmesgpt ./helm/holmes \
  --set registry=me-west1-docker.pkg.dev/robusta-development/development \
  --set image=holmes-dev:e3d603eca \
  --set operator.registry=me-west1-docker.pkg.dev/robusta-development/development \
  --set operator.image=holmes-operator-dev:e3d603eca

Robusta wrapper chart:

helm upgrade --install robusta robusta/robusta \
  --reuse-values \
  --set holmes.registry=me-west1-docker.pkg.dev/robusta-development/development \
  --set holmes.image=holmes-dev:e3d603eca \
  --set holmes.operator.registry=me-west1-docker.pkg.dev/robusta-development/development \
  --set holmes.operator.image=holmes-operator-dev:e3d603eca

@netlify

netlify Bot commented Jun 22, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for holmes-docs ready!

Name Link
🔨 Latest commit 4f2f9ea
🔍 Latest deploy log https://app.netlify.com/projects/holmes-docs/deploys/6a3a31659a907b00085e625d
😎 Deploy Preview https://deploy-preview-2211--holmes-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@holmes/core/tools_utils/oauth_tool_connector.py`:
- Around line 301-302: The except Exception clause at line 301 is flagged by
Ruff as BLE001 (blind exception catching). Add a focused noqa comment to the
except Exception line (e.g., `# noqa: BLE001`) to document that this
intentionally broad catch is by design for best-effort cleanup and token
eviction, which suppresses the lint warning without changing the behavior.
- Around line 311-315: The issue is that when removing a toolset within the lock
in the toolset removal logic, the code removes entries from _user_tools by
toolset.name but removes entries from _user_tool_to_toolset using object
identity comparison (ts is toolset). This causes stale tool_name to toolset
mappings to persist if the toolset was stored as a different object instance
with the same name. Fix this by changing the identity comparison in the
_user_tool_to_toolset cleanup loop to a name-based comparison instead, so that
the removal logic matches the approach used for _user_tools (comparing by
toolset.name rather than object identity).

In `@tests/core/tools_utils/test_oauth_tool_connector_eviction.py`:
- Line 76: The line 76 in test_oauth_tool_connector_eviction.py violates Ruff's
E702 rule because multiple statements are separated by semicolons on a single
line. Split the chained assignments for stale_tool into separate lines: first
create the MagicMock instance, then assign the name property to "k8s_list_pods"
on a new line, and finally assign the toolset property on another new line.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d8c68536-c2ac-4d08-ae76-c5faadc9e77f

📥 Commits

Reviewing files that changed from the base of the PR and between 71a253c and 01ad4f2.

📒 Files selected for processing (2)
  • holmes/core/tools_utils/oauth_tool_connector.py
  • tests/core/tools_utils/test_oauth_tool_connector_eviction.py

Comment thread holmes/core/tools_utils/oauth_tool_connector.py
Comment thread holmes/core/tools_utils/oauth_tool_connector.py
Comment thread tests/core/tools_utils/test_oauth_tool_connector_eviction.py
RoiGlinik and others added 2 commits June 22, 2026 19:07
A reloaded toolset is a new instance with the same name. Identity-only
purge left stale tool→toolset entries behind. Match by name so eviction
survives instance churn.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Roi Glinik <groi.tech@gmail.com>
@RoiGlinik
RoiGlinik enabled auto-merge (squash) June 23, 2026 07:10
@RoiGlinik
RoiGlinik merged commit 04cd99a into master Jun 23, 2026
15 of 20 checks passed
@RoiGlinik
RoiGlinik deleted the worktree-mcp-oauth-token-expiry branch June 23, 2026 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants