Skip to content

fix(providers): refresh Trae's stale Referer/Origin and forward user timezone (#12190) - #13255

Merged
diegosouzapw merged 3 commits into
release/v3.8.51from
fix/12190-trae-referer
Sep 12, 2026
Merged

diegosouzapw merged 3 commits into
release/v3.8.51from
fix/12190-trae-referer

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Root cause

TraeExecutor.buildHeaders() (open-sse/executors/trae.ts) hardcoded Referer: "https://solo.trae.ai/", sent no Origin header at all, and could only ever resolve x-user-region to "US" — none of the three places that build providerSpecificData (the manual import route src/app/api/oauth/trae/import/route.ts, the /authorize callback parser src/app/authorize/parseCallback.ts, and mapTokens() in src/lib/oauth/providers/trae.ts, which both real creation paths bypass) ever populated a non-"US" userRegion or any timezone value. Trae's backend validates Origin/Referer against the JWT session's real origin, which has moved to work.trae.ai, producing a clean 401 even with a fresh, valid token.

Verification of the current upstream expectation

Per the task note, I did not hardcode a new point-in-time domain blindly:

  • Searched the local reference mirrors under _references/_sistemas_proxys/ (command grep, since these dirs are gitignored) for trae.ai — the only hits were the 9router upstream mirror (which carries the same stale solo.trae.ai value we're fixing) and cockpit-tools (a Trae desktop-account manager), which only covers the China (trae.cn) account/checkin surface, not the SOLO/Work remote-agent chat API this executor talks to. Neither is authoritative here.
  • Web search + fetch of https://solo.trae.ai/ and https://work.trae.ai/ today both resolve to the same "TraeWork" product page, confirming solo.trae.ai has been folded into the work.trae.ai surface — consistent with the reporter's finding.
  • Because a live-fetched marketing page is not a guarantee about what the backend's Origin/Referer allow-list checks for indefinitely, the new default is not hardcoded without an escape hatch: it's read from TRAE_WEB_ORIGIN (env, for a fleet-wide bump without a redeploy of code) and can be overridden per-connection via providerSpecificData.refererOrigin, falling back to https://work.trae.ai only when neither is set.

Fix

  • open-sse/executors/trae.ts: buildHeaders() now derives Referer/Origin from TRAE_WEB_ORIGIN env (default https://work.trae.ai) or a per-connection providerSpecificData.refererOrigin override, and forwards x-trae-user-timezone from providerSpecificData.userTimezone when present (omitted otherwise, matching prior behavior for accounts with no timezone on file).
  • src/app/api/oauth/trae/import/route.ts: accepts optional userRegion/userTimezone fields instead of hardcoding providerSpecificData.userRegion: "US"; exposes them in the GET field-metadata so the dashboard import form can capture them. Default stays "US" when the caller leaves them blank, so existing imports keep behaving as before.
  • src/shared/validation/schemas/auth.ts: traeImportSchema gains optional userRegion/userTimezone.
  • src/app/authorize/parseCallback.ts: best-effort forwards userRegion/userTimezone from the OAuth callback's userInfo payload if Trae ever includes them under UserRegion/Timezone; stays undefined (i.e. no behavior change) otherwise, since I could not find prior evidence these keys exist in this payload.
  • src/lib/oauth/providers/trae.ts: mapTokens() also accepts userTimezone/user_timezone for parity, though both direct creation paths above bypass this function already (pre-existing, noted in the original triage).

Regression test

tests/unit/trae-headers-12190.test.ts (new file). RED before the fix (matches the plan's proven repro exactly):

✖ issue #12190: buildHeaders sends the current work.trae.ai Origin/Referer, not stale solo.trae.ai
  actual: 'https://solo.trae.ai/', expected: 'https://work.trae.ai/'
✖ issue #12190: buildHeaders forwards x-trae-user-timezone from providerSpecificData when present
  actual: undefined, expected: 'America/Recife'
✖ issue #12190: buildHeaders lets a per-connection refererOrigin override the default web origin
  actual: undefined, expected: 'https://solo.trae.ai'

GREEN after the fix — all 6 cases pass (freshness, timezone forwarding, timezone omission when absent, custom userRegion respected, default region, per-connection origin override).

Gates run

  • node --import tsx/esm --test tests/unit/trae-headers-12190.test.ts → 6/6 pass (new)
  • node --import tsx/esm --test tests/unit/trae-executor.test.ts → 16/16 pass (existing, unmodified — no assertion on Referer/Origin values existed, so nothing needed realigning)
  • node --import tsx/esm --test tests/unit/oauth-trae.test.ts → 13/13 pass (existing, unmodified)
  • node scripts/check/check-file-size.mjs → OK
  • node scripts/check/check-complexity.mjs → OK
  • node scripts/check/check-cognitive-complexity.mjs → OK
  • npm run typecheck:core → exit 0
  • npx eslint --suppressions-location config/quality/eslint-suppressions.json <changed files> → exit 0
  • node scripts/check/check-changelog-integrity.mjs → OK

⚠️ base-red inherited: #12732 — unit #12058, integration codex-cache, package-artifact, tarball-smoke, agent-skills-sync

Closes #12190

@diegosouzapw
diegosouzapw merged commit 1fb7d5d into release/v3.8.51 Sep 12, 2026
13 of 21 checks passed
Githab-capibara added a commit to Githab-capibara/OmniRoute that referenced this pull request Sep 17, 2026
…timezone (cheaper-inference#12190) (cheaper-inference#13255)

Merged as part of the owner batch of 2026-09-11.

This PR had a live worktree in another session, so it sat outside the main 39. Merged on your explicit call, validated first rather than taken on trust: boarded with the other 10 worktree-held PRs into a consolidated worktree off `release/v3.8.51`.

- ESLint over every changed file: no errors
- `typecheck:core` clean; `check:dashboard-typecheck` OK; `check:changelog-integrity` OK
- complexity 2821 / baseline 3218 and cognitive-complexity 1272 / baseline 1437
- 203 of 208 assertions green. The 5 remaining (`guide-settings-route` ×4, `hard-session-lease-bypass-inventory` ×1) reproduce on the pure tip with nothing from this batch applied.
- `imageGeneration.ts` rebaselined 3259 → 3293 for cheaper-inference#12945's image-only-model guard, landed separately in cheaper-inference#13392 so nothing was pushed onto a live branch.

⚠️ base-red inherited: cheaper-inference#12732 — provider count 356 vs 358 and `open-sse/utils/stream.ts` 3115 > frozen 3098, both reproducing on the pure tip.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…timezone (cheaper-inference#12190) (cheaper-inference#13255)

Merged as part of the owner batch of 2026-09-11.

This PR had a live worktree in another session, so it sat outside the main 39. Merged on your explicit call, validated first rather than taken on trust: boarded with the other 10 worktree-held PRs into a consolidated worktree off `release/v3.8.51`.

- ESLint over every changed file: no errors
- `typecheck:core` clean; `check:dashboard-typecheck` OK; `check:changelog-integrity` OK
- complexity 2821 / baseline 3218 and cognitive-complexity 1272 / baseline 1437
- 203 of 208 assertions green. The 5 remaining (`guide-settings-route` ×4, `hard-session-lease-bypass-inventory` ×1) reproduce on the pure tip with nothing from this batch applied.
- `imageGeneration.ts` rebaselined 3259 → 3293 for cheaper-inference#12945's image-only-model guard, landed separately in cheaper-inference#13392 so nothing was pushed onto a live branch.

⚠️ base-red inherited: cheaper-inference#12732 — provider count 356 vs 358 and `open-sse/utils/stream.ts` 3115 > frozen 3098, both reproducing on the pure tip.
@diegosouzapw
diegosouzapw deleted the fix/12190-trae-referer branch October 18, 2026 23:48
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.

fix(providers): Trae import-token connections fail with 401 from stale Referer/Origin/region defaults

1 participant