Skip to content

fix(providers): add official opencode client User-Agent to opencode-free - #2067

Closed
waw4303 wants to merge 1 commit into
lidge-jun:devfrom
waw4303:fix/opencode-free-cli-headers
Closed

fix(providers): add official opencode client User-Agent to opencode-free#2067
waw4303 wants to merge 1 commit into
lidge-jun:devfrom
waw4303:fix/opencode-free-cli-headers

Conversation

@waw4303

@waw4303 waw4303 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Problem

Requests to OpenCode Free (https://opencode.ai/zen/v1/chat/completions) currently fail with 429 Too Many Requests / FreeUsageLimitError:

{"type":"error","error":{"type":"FreeUsageLimitError","message":"Error from provider (Console): Rate limit exceeded. Please try again later."}}

This occurs because the OpenCode API gateway rejects requests carrying generic/browser User-Agent strings alongside x-opencode-client: desktop, requiring the official client User-Agent prefix (opencode) used by the official @opencode-ai/desktop and CLI applications.

Solution

Add the canonical User-Agent: opencode header to staticHeaders for opencode-free in src/providers/registry.ts, while preserving the existing desktop client identity (x-opencode-client: desktop) and avoiding fragile CLI-specific version strings or unnecessary project headers:

  • User-Agent: opencode (matches the root client family opencode/${version} from @opencode-ai/desktop bundle out/main/chunks/node-4IhTfWZ9.js)
  • x-opencode-client: desktop (preserves the desktop tier identity and documentation consistency)

Verification

  • Decompiled and inspected @opencode-ai/desktop (v1.18.18) app bundle (USER_AGENT = "opencode/" + InstallationVersion).
  • Tested live against https://opencode.ai/zen/v1/chat/completions across header variations:
    • User-Agent: opencode + x-opencode-client: desktop -> 200 OK
    • generic User-Agent + x-opencode-client: desktop -> 429 FreeUsageLimitError
  • bun test tests/opencode-free-provider.test.ts passes.
  • bun test tests/management-provider-validation.test.ts passes.
  • bun run typecheck (tsc --noEmit) passes cleanly.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Bug Fixes
    • Added the User-Agent: opencode header to requests made through the OpenCode Free provider.
    • Ensured provider-managed headers are preserved when clearing or updating configuration.
    • Improved consistency of headers across configured and unauthenticated requests.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Aug 18, 2026
@github-actions github-actions Bot changed the title fix(providers): update opencode-free static headers to official CLI markers [WRONG BRANCH] fix(providers): update opencode-free static headers to official CLI markers Aug 18, 2026
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • review readiness checklist open (0/4 boxes ticked).

What to do

  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ All CI tests are green on my local testing.
  • ⬜ I pushed my PR to the latest dev commit.
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

This PR stays in draft until every box above is ticked.

@github-actions
github-actions Bot marked this pull request as draft August 18, 2026 19:00
@coderabbitai

coderabbitai Bot commented Aug 18, 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fea86c8f-14e5-492c-9015-326569faa249

📥 Commits

Reviewing files that changed from the base of the PR and between a5183ab and 6a79c42.

📒 Files selected for processing (3)
  • src/providers/registry.ts
  • tests/management-provider-validation.test.ts
  • tests/opencode-free-provider.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The opencode-free provider now sends User-Agent: opencode. Tests verify the header in static configuration, seeded configuration, unauthenticated requests, and preserved configuration after header clearing.

Changes

OpenCode CLI provider headers

Layer / File(s) Summary
CLI header contract
src/providers/registry.ts, tests/opencode-free-provider.test.ts
The opencode-free provider adds User-Agent: opencode. Tests verify the header in static headers, seeded headers, and unauthenticated adapter requests.
Managed header preservation
tests/management-provider-validation.test.ts
Header-clearing tests verify that User-Agent: opencode and x-opencode-client remain in memory and persisted configuration.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Merge Risk: 🟡 Moderate · up to 6a79c

The code change is narrowly scoped, but required CI, branch, findings, and readiness confirmations are still incomplete, so merge should wait until those gates are satisfied.

Suggested labels: review-ready

Suggested reviewers: ingwannu

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding the official OpenCode client User-Agent to the opencode-free provider.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@waw4303
waw4303 force-pushed the fix/opencode-free-cli-headers branch from d6ec3b0 to a5183ab Compare August 18, 2026 19:08
@waw4303 waw4303 changed the title [WRONG BRANCH] fix(providers): update opencode-free static headers to official CLI markers fix(providers): update opencode-free static headers to official CLI markers Aug 18, 2026
@waw4303
waw4303 changed the base branch from main to dev August 18, 2026 19:08
@waw4303
waw4303 marked this pull request as ready for review August 18, 2026 19:08
@github-actions
github-actions Bot marked this pull request as draft August 18, 2026 19:09
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@waw4303
waw4303 marked this pull request as ready for review August 18, 2026 19:11
@github-actions
github-actions Bot marked this pull request as draft August 18, 2026 19:12
@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 23 / 80

draft 이고 readiness 체크 4칸이 전부 비어 있습니다. 변경은 src/providers/registry.tsopencode-free staticHeaders 세 줄과 그 값을 그대로 기대하는 테스트 두 파일입니다. x-opencode-client: desktop 을 빼고 User-Agent: opencode-cli/1.0.0, x-opencode-client: cli, x-opencode-project: default 를 넣습니다. 본문은 Zen 게이트웨이가 desktop 마커를 거부하고 official CLI 헤더만 받는다고 합니다. 로컬에서 200 을 봤다는 서술만 있고 CI 초록 표시는 없습니다.

헤더 교체는 레지스트리 시드와 adapter buildRequest 경로에 바로 붙습니다. tests/opencode-free-provider.test.ts 는 Authorization 이 없을 때와 user key 가 있을 때 모두 새 정적 헤더가 남는지만 봅니다. tests/management-provider-validation.test.tsheaders: null PATCH 후에도 레지스트리 소유 정적 메타가 남는 회귀를 새 세 키로 바꿨습니다. 429 / FreeUsageLimitError 본문을 분류하거나 Retry-After 없는 단윈도우를 검증하는 테스트는 이 diff 에 없습니다. 게이트웨이가 헤더를 거부한다는 주장은 코드로 고정되어 있지 않습니다.

User-Agentopencode-cli/1.0.0 으로 하드코딩됩니다. 실제 CLI 버전이 바뀌면 이 값이 다시 막힐 수 있고, 이 저장소의 다른 클라이언트 핑거프린트와 버전이 어긋납니다. x-opencode-project: default 는 프로젝트 격리용 헤더로 보이는데, 모든 opencode-free 요청을 한 버킷으로 묶습니다. 기존 note 는 여전히 "public desktop tier" 와 Zen 데이터 사용 경고를 쓰지만 전송 신원은 cli 로 바뀌었습니다. 문서/노트와 wire 계약이 어긋납니다.

이 패치는 desktop 클라이언트가 CLI 로 보이도록 헤더를 맞춥니다. 게이트웨이의 무료 티어 제한을 우회하는 방향이라, 헤더 문자열이 맞는지보다 이 프로바이더를 계속 desktop 으로 둘지 CLI 계약으로 공식 이전할지가 먼저입니다. 테스트는 기댓값만 갈아끼웠기 때문에 잘못된 헤더여도 초록이 됩니다.

해결방안: draft 체크리스트를 채우기 전에, opencode-free 를 CLI 계약으로 바꿀지 유지할지 결정하고 note / docs 를 같은 신원으로 맞추십시오. User-Agent 를 매직 스트링으로 두지 말고 실제 CLI 버전 소스와 맞출 방법을 적으십시오. x-opencode-project 를 항상 default 로 보낼지가 의도인지 확인하고, 429 본문 분류 테스트가 필요하면 헤더 equality 밖에 추가하십시오. ready 가 아니면 draft 를 유지하십시오.

이 댓글은 grok-bot이 작성했습니다

OpenCode's Zen gateway requires the official client User-Agent prefix
('opencode') alongside the client marker, answering 429/403 to generic
fetch User-Agents. Keep the desktop tier identity and add the canonical
User-Agent header.
@waw4303
waw4303 force-pushed the fix/opencode-free-cli-headers branch from a5183ab to 6a79c42 Compare August 19, 2026 23:09
@waw4303 waw4303 changed the title fix(providers): update opencode-free static headers to official CLI markers fix(providers): add official opencode client User-Agent to opencode-free Aug 19, 2026
@waw4303
waw4303 marked this pull request as ready for review August 19, 2026 23:09
@waw4303

waw4303 commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review! We investigated the official @opencode-ai/desktop bundle (v1.18.18, out/main/chunks/node-4IhTfWZ9.js) and verified how the gateway handles requests:

  1. Root cause of 429/403: The OpenCode Zen gateway filters on the User-Agent prefix rather than refusing the desktop tier. A generic User-Agent with x-opencode-client: desktop fails with 429 FreeUsageLimitError, whereas User-Agent: opencode with x-opencode-client: desktop succeeds with 200 OK.
  2. Canonical resolution:
    • Replaced the magic CLI version string and dropped x-opencode-project.
    • Added User-Agent: opencode (the canonical client family prefix matching opencode/).
    • Kept x-opencode-client: desktop and preserved the note / desktop documentation as intended.
  3. Rebased onto the latest dev branch, tests updated and passing (84/84), bun run typecheck clean.

@lidge-jun

Copy link
Copy Markdown
Owner

Thank you @waw4303 — and thank you for revising this. Absorbed as #2160.

Your revised head is the right call and I want to be explicit about why, because the reasoning came from outside this repository. Checking OmniRoute — an independent open-source project brokering the same Zen upstream — its open-sse/executors/opencode.ts defaults to exactly the pair you landed on:

userAgent: ... || "opencode",
client:    ... || "desktop",

and it got there by deliberately retreating from its own earlier opencode-cli/1.0.0 pin. So two projects solving the identical problem converged on the unversioned marker independently. That is much stronger evidence than either of us reasoning alone, and it is why your second version landed where your first did not.

One thing your patch could not have known about, which is why the replacement is larger than your diff: the registry edit alone would have reached nobody. staticHeaders is documented as merged into every upstream request, but it was only ever copied at seed time. I verified it directly:

persisted config routedProviderConfig(...).headers
no headers block undefined
{x-opencode-client: desktop} unchanged — no UA

Every existing opencode-free install would have kept the bare Bun UA forever. #2160 therefore also merges registry static headers beneath user headers at route time and in model discovery, matched case-insensitively so a user's user-agent override replaces rather than duplicates (a plain spread would have produced "custom-agent, opencode" on the wire).

Your test assertions are carried over, plus five that fail if the delivery path is reverted. Full suite is 13519 pass / 0 fail.

Closing this in favor of #2160, with the finding credited to you. Genuinely useful report — it surfaced a bug in the header mechanism itself, not just in one provider's values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants