OpenHands / OpenHands/software-agent-sdk
[Bug]: Retired gemini-cli OAuth outranks a working API key, and the ACP Gemini pin is badly stale
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 539
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 137
Description
Bug Description
Two defects in the ACP Gemini path, both consequences of Google's 2026-06-18 consumer-tier cutoff, and neither requiring a provider migration to fix.
1. A retired auth method outranks a working one. _select_auth_method in openhands-sdk/openhands/sdk/agent/acp_agent.py ranks file-backed logins above API keys by design:
vertex-ai → oauth-personal → gemini-api-key
That order was correct while personal Google OAuth worked. It no longer does — Google stopped serving oauth-personal for Google AI Pro/Ultra and free tiers on 2026-06-18. Any developer who has ever run gemini login has a stale ~/.gemini/oauth_creds.json on disk, so the SDK selects the dead method and the session fails with This client is no longer supported for Gemini Code Assist for individuals — even when a valid GEMINI_API_KEY is present in the environment.
_auth_selection_failure_reason has no arm for this either, so the log reports the generic "no supported credential source is available" rather than naming the retired login.
2. Agent Canvas repeats the same mistake independently. The onboarding probe in OpenHands/OpenHands at src/api/acp-service/acp-service.api.ts is literally:
test -f "$HOME/.gemini/oauth_creds.json" && echo present || echo absent
It reports authenticated for a credential that cannot authenticate, which hides the API-key fields exactly when the user needs them.
3. The pin is eleven minors stale. GEMINI_CLI_VERSION is 0.46.0; upstream stable is 0.57.0 (released 2026-08-25). The gap keeps widening — Gemini CLI ships stable releases roughly weekly, so treat the target as latest stable at implementation time rather than a number frozen in this issue. @google/gemini-cli is not deprecated — it is Apache-2.0, actively published (nightlies daily, ~393k downloads/week), and --acp remains supported and documented. Only the consumer OAuth tier was retired; API-key, Vertex AI, and Gemini Code Assist Standard/Enterprise all continue. A separate, staler 0.38.0 pin also exists in benchmarks/utils/Dockerfile.agent-layer-commit0.
Expected Behavior
- A present-and-valid
GEMINI_API_KEY(orGOOGLE_APPLICATION_CREDENTIALS) is used even when a stale~/.gemini/oauth_creds.jsonexists on disk. - When no usable credential exists, the warning names the retired
oauth-personallogin and points at the API-key / service-account alternatives. - Agent Canvas onboarding does not present a retired Google login as a working authentication state.
- The pinned Gemini CLI tracks a currently supported upstream release.
Actual Behavior
oauth-personal wins over a working API key. Reproduced against main:
mkdir -p ~/.gemini && echo '{}' > ~/.gemini/oauth_creds.json
uv run python -c "
from types import SimpleNamespace
from openhands.sdk.agent.acp_agent import _select_auth_method
methods = [SimpleNamespace(id='oauth-personal'), SimpleNamespace(id='gemini-api-key')]
print(_select_auth_method(methods, {'GEMINI_API_KEY': 'a-valid-key'}))
"
Prints oauth-personal; expected gemini-api-key. In a real session that selection then fails at conn.authenticate(...) with the retired-client error, despite a usable key being available.
Existing coverage lives in tests/sdk/agent/test_acp_agent.py (search oauth_creds.json) and encodes the current precedence, so those cases need updating alongside the fix:
uv run pytest tests/sdk/agent/test_acp_agent.py -k "auth_method"
Steps to Reproduce
- Create a stale credentials file:
mkdir -p ~/.gemini && echo '{}' > ~/.gemini/oauth_creds.json. - Export a valid
GEMINI_API_KEY. - Start an ACP conversation with
acp_server="gemini-cli"on a consumer-tier Google account. - Observe
Authenticating with ACP method: oauth-personalin the logs, followed by the retired-client failure.
Acceptance Criteria
-
_select_auth_methodranksgemini-api-keyaboveoauth-personal, so a stale credentials file no longer shadows a working API key.vertex-aikeeps its existing top precedence. -
_auth_selection_failure_reasonnames the retiredoauth-personallogin when it is offered but unusable, instead of the generic "no supported credential source" message. -
tests/sdk/agent/test_acp_agent.pycovers the stale-file-plus-valid-key case and assertsgemini-api-keyis selected. -
GEMINI_CLI_VERSIONis bumped from0.46.0to the latest stable release at implementation time (0.57.0as of 2026-08-26) inopenhands-sdk/openhands/sdk/settings/acp_providers.pyand the matchingnpm install -gline inopenhands-agent-server/openhands/agent_server/docker/Dockerfilein the same change — the registry comment requires both to move together. -
default_session_modeand_GEMINI_MODELSare re-verified against whichever version is pinned rather than bumped blind; theset_session_mode("yolo")rejection (#3772) and the flash-id re-resolution (#3532) are both version-sensitive. -
benchmarks/utils/Dockerfile.agent-layer-commit0no longer pins0.38.0. - Agent Canvas onboarding (
OpenHands/OpenHands,src/api/acp-service/acp-service.api.ts) stops treating~/.gemini/oauth_creds.jsonas proof of a usable login and steers consumer-tier users to an API key or service account. -
docs/ACP_AGENTS.mdno longer lists Google login as a supported Gemini ACP auth option. - A live-ACP e2e run against
vertex-aipasses on the bumped pin.
Out of Scope
Adding Antigravity CLI (agy) as an ACP provider. That is tracked separately in #4624, which has been reopened now that Google's first-party ACP server (agy_acp_server, distributed from dl.google.com, registry entry authored by Google LLC) has been confirmed to exist. It is strictly additive — gemini-cli is never removed, since it is a validated Literal in persisted settings, a value in the enterprise acpserver tag column, and a published leaderboard label.
No deployed OpenHands path is affected by the Gemini CLI consumer-tier cutoff: cloud and enterprise authenticate via vertex-ai service accounts, and benchmark and evaluation runs via GEMINI_API_KEY. Both paths Google has confirmed continue unchanged. That is what makes this issue maintenance rather than an incident.
Sequencing note: the auth-precedence fix here and the new gemini-api-key / agent-platform arms needed by #4624 touch the same function (_select_auth_method). Whichever merges second should rebase rather than reintroduce the old ordering.
Context
- Split out of #4624, which is now scoped to additive Antigravity provider support. This issue is the Gemini-CLI maintenance track and is independent of it.
- OpenHands/enterprise#235 tracks the enterprise-side branding, secrets, and analytics work for the new provider; it follows #4624, not this issue.
Note for whoever picks up #4624: adding an ACP provider key touches seven repositories, and two of them are easy to miss. typescript-client is a generated mirror that Agent Canvas and enterprise read the registry through, and openhands-index-results owns the AgentName enum that gates leaderboard pushes — its value must land before evaluation can publish under a new agent type.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with _select_auth_method and _auth_selection_failure_reason in openhands-sdk/openhands/sdk/agent/acp_agent.py, then run tests/sdk/agent/test_acp_agent.py -k "auth_method". Review the Gemini version and mode references in acp_providers.py, both Dockerfiles, the Agent Canvas onboarding API, and docs/ACP_AGENTS.md. Done means the acceptance criteria pass across auth selection, version pins, onboarding, documentation, and the live ACP check.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dockerfile, google-cloud, python, typescript
- Domain
- authentication, backend, devtools, documentation, testing
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100