fix(contracts): decode ServerProviders forward-compatibly - #5327
Conversation
ServerProviders is Schema.Array(ServerProvider), and ServerProvider has several nested literal-union status fields (ServerProviderState, ServerProviderAuthStatus, ServerProviderVersionAdvisoryStatus, ServerProviderUpdateStatus). Adding a new member to any of them makes an older client's whole `providers` array fail to decode, and since `providers` lives inside `ServerConfig`, that takes down the entire config decode — the client's initial sync gate on every WS connection. pingdotgg#5055 added ForwardCompatibleArray for exactly this class of union (keybinding issues, editor ids) but ServerProviders was left on Schema.Array. This wraps it the same way: an unknown provider element gets dropped instead of failing the array, so an older client keeps every other provider it can render instead of losing the connection entirely.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
ApprovabilityVerdict: Approved dc16ad8 This is a straightforward bug fix applying an existing forward-compatibility pattern ( You can customize Macroscope's approvability policy. Learn more. |
## What's Changed * fix(web): blink the terminal cursor again by @StiensWout in pingdotgg/t3code#5314 * fix(terminal): protect held Ctrl/Cmd+W close shortcut by @StiensWout in pingdotgg/t3code#5322 * fix(server): strip replayable terminal queries from history by @StiensWout in pingdotgg/t3code#5319 * fix(contracts): decode ServerProviders forward-compatibly by @Brechard in pingdotgg/t3code#5327 * fix(web): simplify chat code blocks by @t3-code[bot] in pingdotgg/t3code#5301 * fix(web): align multiline error alert controls by @t3-code[bot] in pingdotgg/t3code#5304 * Upgrade Effect to beta.103 by @juliusmarminge in pingdotgg/t3code#5331 ## New Contributors * @Brechard made their first contribution in pingdotgg/t3code#5327 **Full Changelog**: pingdotgg/t3code@v0.0.32-nightly.20260804.993...v0.0.32-nightly.20260804.997 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.32-nightly.20260804.997
…5327) Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
…5327) Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
…5327) Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
…5327) Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
…5327) Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>
…ffect beta.103 67 upstream commits (through 6b73b3d): paginated thread loading with user-anchored turn windows (pingdotgg#5493), contract-backed fonts (pingdotgg#5103), subagent/workflow observability agents panel (pingdotgg#5219), sidebar-v2 thread pinning (pingdotgg#5312, migrations 036/037), scannable pairing QR (pingdotgg#5360), MCP tool-result trimming (pingdotgg#5482), renderer OOM containment (pingdotgg#5148), tunnel survives updates/stops, terminal polish batch, forward-compat ServerProviders decode (pingdotgg#5327), Effect beta.103, many fixes. Forma preserved: composer surface/footer, ComposerMetaBar, diff panel skin, RightPanelTabs Forma strip/icons with BOTH componentPreview and agents surfaces, sidebar tone map, forma:// CORS origins, ~/.forma, fork migrations 935-941 after upstream 036/037, fork contract fields alongside fonts/threadPinning. Fonts unification starts (terminal now settings-driven); fix-forward follows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
## What's Changed * fix(mobile): reduce thread feed scroll jank by @gabrielelpidio in pingdotgg/t3code#4874 * fix(web): restore sidebar v2 thread actions and terminal icon by @Noojuno in pingdotgg/t3code#4712 * fix(web): settle button now works on hover, not just right-click by @t3dotgg in pingdotgg/t3code#4905 * fix(clients): disable add project while disconnected by @StiensWout in pingdotgg/t3code#4834 * fix(composer): hide default Codex service tier by @maxktz in pingdotgg/t3code#4784 * docs: link iOS and Android app store downloads by @t3dotgg in pingdotgg/t3code#4902 * fix(web): align remote server update action by @StiensWout in pingdotgg/t3code#4731 * fix(connect): suggest a serve command that matches how you ran connect by @t3dotgg in pingdotgg/t3code#4897 * fix(mobile): stop shared content errors in Personal Team builds by @t3dotgg in pingdotgg/t3code#4943 * perf(mobile): sends respond instantly, thread opens stop freezing by @t3dotgg in pingdotgg/t3code#4882 * fix(web): show Codex fast mode as a bolt by @t3dotgg in pingdotgg/t3code#4947 * docs: seed worktrees with a copy of real userdata instead of banning it by @t3dotgg in pingdotgg/t3code#4949 * fix(mobile): support dragged images in the composer by @t3dotgg in pingdotgg/t3code#4953 * fix(mobile): stop long iOS threads from jumping while scrolling up by @t3dotgg in pingdotgg/t3code#4867 * fix(web): keep worktree default when switching a draft's machine by @t3dotgg in pingdotgg/t3code#4964 * perf(mobile): reconnect environments immediately on resume by @t3dotgg in pingdotgg/t3code#4878 * feat(web): pasting a huge screenshot now compresses it instead of erroring by @t3dotgg in pingdotgg/t3code#4967 * feat(web): regenerate thread titles from sidebar by @t3dotgg in pingdotgg/t3code#4810 * fix(web): show server update progress through reconnect by @t3dotgg in pingdotgg/t3code#4903 * feat(search): find threads by conversation content by @t3dotgg in pingdotgg/t3code#4959 * fix: marketing site Vercel builds no longer die after ~100 deploys by @t3dotgg in pingdotgg/t3code#4975 * docs: split user and maintainer docs, fix 100+ stale claims by @t3dotgg in pingdotgg/t3code#4807 * fix(web): server updates no longer look like warnings by @t3dotgg in pingdotgg/t3code#4992 * fix(connect): reboots no longer strand the relay link, 403s now say why by @t3dotgg in pingdotgg/t3code#4988 * Add project file picker (⌘P) and project content search (⇧⌘F) by @jakeleventhal in pingdotgg/t3code#4855 * Check for mobile app updates on launch by @juliusmarminge in pingdotgg/t3code#4958 * fix(mobile): support pre-Liquid-Glass iOS bottom toolbar by @gabrielelpidio in pingdotgg/t3code#4984 * fix(server): restore PR detection without HOME by @StiensWout in pingdotgg/t3code#4985 * fix(web): fill fast mode icon by @maria-rcks in pingdotgg/t3code#5004 * fix: cache project favicons across web and mobile by @gabrielelpidio in pingdotgg/t3code#4767 * perf(ci): cut stale runs and redundant setup by @t3dotgg in pingdotgg/t3code#4802 * style(web): make scroll-to-end pill translucent by @maria-rcks in pingdotgg/t3code#5036 * fix(desktop): bump Clerk Electron SDK to 0.0.24 and register t3code:// scheme on Linux by @juliusmarminge in pingdotgg/t3code#5015 * perf(server): cache default branch name and origin existence across status refreshes by @UtkarshUsername in pingdotgg/t3code#5008 * feat(shared): support shorthand (major-only) versions in the semver helpers by @arhxam in pingdotgg/t3code#5027 * fix(mobile): remove unnecessary photo library permission by @skjiisa in pingdotgg/t3code#4929 * fix(shared): lenient JSON parser deletes commas inside string values by @arhxam in pingdotgg/t3code#5025 * fix(mobile): default bare IP pairing to HTTP by @Lucenx9 in pingdotgg/t3code#4990 * fix(mobile): restore iOS Threads branding by @PixPMusic in pingdotgg/t3code#4862 * chore: add mobile issue template area by @MaxAnderson95 in pingdotgg/t3code#4895 * fix(desktop): link release notes from the update downloaded toast by @Sy-D in pingdotgg/t3code#4771 * fix(mobile): accept Android clipboard images in composer by @adityavardhansharma in pingdotgg/t3code#4836 * fix(mobile): show the correct build channel in Android's Threads page header by @PixPMusic in pingdotgg/t3code#4861 * fix(contracts): decode growing config unions forward-compatibly by @juliusmarminge in pingdotgg/t3code#5055 * fix(mobile): server model, worktree, and origin preferences now apply to new tasks by @t3dotgg in pingdotgg/t3code#5064 * fix(ci): repair the mobile showcase screenshots workflow by @juliusmarminge in pingdotgg/t3code#5057 * fix(ci): capture iPad App Store screenshots in landscape by @PixPMusic in pingdotgg/t3code#5065 * fix(oxlint-plugin): Resolve the oxlint bin without assuming a pnpm layout by @mwolson in pingdotgg/t3code#5066 * feat(cli): `npx t3 pair` - generate QR code from a running server by @t3dotgg in pingdotgg/t3code#4955 * fix(server): self-update no longer rolls itself back on restart by @t3dotgg in pingdotgg/t3code#5095 * fix(ci): rotate iPad showcase captures without Simulator UI scripting by @juliusmarminge in pingdotgg/t3code#5094 * feat(web): render terminals with libghostty-vt by @StiensWout in pingdotgg/t3code#4860 * refactor: move the canonical libghostty-vt vendor to the repository root by @StiensWout in pingdotgg/t3code#5102 * feat(mobile): add thread snoozing by @gabrielelpidio in pingdotgg/t3code#5053 * feat(mobile): make settled threads collapsible by @PixPMusic in pingdotgg/t3code#5056 * follow-up normalization after #4700. by @shivamhwp in pingdotgg/t3code#4498 * feat(web): search threads from the sidebar by @shivamhwp in pingdotgg/t3code#4769 * feat(web): add settings sidebar search by @shivamhwp in pingdotgg/t3code#4682 * fix: threads with open PRs no longer auto-settle by @t3dotgg in pingdotgg/t3code#5151 * fix(server): bound thread catch-up replay and stop full-DB snapshot hydration by @t3dotgg in pingdotgg/t3code#5147 * fix(server): follow branch drift in dedicated worktrees so PRs link to their thread by @t3dotgg in pingdotgg/t3code#5159 * fix(server): make remote updates rollback-safe by @t3dotgg in pingdotgg/t3code#5181 * fix(web): stop settle controls overlapping the status label by @ipanasenko in pingdotgg/t3code#4574 * fix: normalize app icon glyph sizing by @t3-code[bot] in pingdotgg/t3code#5202 * fix(server): surface cloudflared FTL/PNC relay logs as warnings, not debug by @arhxam in pingdotgg/t3code#5076 * fix(server): stop npx service updates from silently leaving the old server running by @t3dotgg in pingdotgg/t3code#5217 * feat: fold legacy models into separate menus by @t3dotgg in pingdotgg/t3code#5190 * fix(desktop): claim the t3code:// scheme default on Linux at startup by @juliusmarminge in pingdotgg/t3code#5054 * fix(web): polish interface spacing by @maria-rcks in pingdotgg/t3code#5252 * fix(desktop): Niri/Hyprland - Linux secret storage backend by @mwolson in pingdotgg/t3code#2916 * fix(web): match loading screen to dark theme by @t3-code[bot] in pingdotgg/t3code#5303 * fix(web): blink the terminal cursor again by @StiensWout in pingdotgg/t3code#5314 * fix(terminal): protect held Ctrl/Cmd+W close shortcut by @StiensWout in pingdotgg/t3code#5322 * fix(server): strip replayable terminal queries from history by @StiensWout in pingdotgg/t3code#5319 * fix(contracts): decode ServerProviders forward-compatibly by @Brechard in pingdotgg/t3code#5327 * fix(web): simplify chat code blocks by @t3-code[bot] in pingdotgg/t3code#5301 * fix(web): align multiline error alert controls by @t3-code[bot] in pingdotgg/t3code#5304 * Upgrade Effect to beta.103 by @juliusmarminge in pingdotgg/t3code#5331 * fix(web): increase tooltip z-index to overlay popovers and menus by @naMqe-h in pingdotgg/t3code#5326 * fix(server): use a Cursor todo's title when its content is blank by @arhxam in pingdotgg/t3code#5073 * fix(ssh): isolate managed tunnel processes by @nateEc in pingdotgg/t3code#4347 * fix(server): scrub AppImage XDG_DATA_DIRS and GSETTINGS_SCHEMA_DIR from terminals by @arhxam in pingdotgg/t3code#5075 * fix(mobile): show correct provider icons for Grok, Cursor, and OpenCode by @Wraient in pingdotgg/t3code#4586 * fix(web): stop the chat timeline reading through the provider status banner by @Bil0000 in pingdotgg/t3code#5353 * fix(desktop,web): contain renderer memory growth and recover from renderer OOM crashes by @t3dotgg in pingdotgg/t3code#5148 * fix(server): generate durable thread titles by @t3dotgg in pingdotgg/t3code#5357 * fix(web): better right panel (new diffs styling) by @maria-rcks in pingdotgg/t3code#5260 * fix(server): keep regenerated titles on topic by @t3dotgg in pingdotgg/t3code#5365 * refactor(server): make title prompts plaintext by @t3dotgg in pingdotgg/t3code#5368 * feat(web): configurable fonts and sizes under Settings → Appearance by @StiensWout in pingdotgg/t3code#5103 * feat(sidebar-v2): bring back thread pinning by @t3dotgg in pingdotgg/t3code#5312 * feat(web): make pairing QR codes actually scannable, with endpoint choice by @t3dotgg in pingdotgg/t3code#5360 * fix(desktop,web): improve in-app browser shortcuts and URL behavior by @t3dotgg in pingdotgg/t3code#4703 * fix(web): prevent legacy model picker layout shift by @FllipEis in pingdotgg/t3code#5349 * fix(server): allow remote updates with database migrations by @t3dotgg in pingdotgg/t3code#5374 * fix(mcp): unblock Kimi models in OpenCode with preview tools by @hwanseoc in pingdotgg/t3code#5128 * fix(web): clear main branch lint warnings by @t3dotgg in pingdotgg/t3code#5384 * fix(mobile): preserve grouped project workspaces by @shivamhwp in pingdotgg/t3code#4642 * fix(mobile): prevent Android thread search crash by @shivamhwp in pingdotgg/t3code#5386 * fix(web): truncate long project switcher names by @FllipEis in pingdotgg/t3code#5348 * fix(mobile): avoid double dividers between thread sections by @shivamhwp in pingdotgg/t3code#5391 * fix(web): keep the composer command menu anchored to the composer by @StiensWout in pingdotgg/t3code#5336 * fix(web): restore terminal link hover styles by @StiensWout in pingdotgg/t3code#5382 * fix(ci): isolate releases from shared API rate limits by @t3dotgg in pingdotgg/t3code#5394 * fix(web): keep model picker shortcuts in sync by @t3dotgg in pingdotgg/t3code#5400 * fix(web): keep terminal font settings reliable by @StiensWout in pingdotgg/t3code#5397 * Enrich terminal font previews by @juliusmarminge in pingdotgg/t3code#5428 * fix(web): preserve terminal font size when splitting by @t3-code[bot] in pingdotgg/t3code#5444 * Prevent terminal loading flash by @juliusmarminge in pingdotgg/t3code#5432 * fix: reconnect faster after remote server updates by @t3dotgg in pingdotgg/t3code#5404 * feat: native subagent & workflow observability by @t3dotgg in pingdotgg/t3code#5219 * perf(server): stop shipping full MCP tool results in thread payloads by @t3dotgg in pingdotgg/t3code#5482 * fix(web): closed plan sidebar stays closed when returning to a thread by @t3dotgg in pingdotgg/t3code#5484 * fix: respect time format for sidebar snooze by @huxcrux in pingdotgg/t3code#4438 * fix: smooth remote server updates by @t3dotgg in pingdotgg/t3code#5470 * fix(server): drop superseded tool updates from snapshots by @t3dotgg in pingdotgg/t3code#5483 * fix(web): clarify auto permission fallback by @t3-code[bot] in pingdotgg/t3code#5431 * fix(acp): keep unknown approvals actionable by @t3-code[bot] in pingdotgg/t3code#5430 * fix(mobile): stop thread messages reading through pending cards by @carlosricojr in pingdotgg/t3code#5450 * fix(web): align composer inline chips with prompt text by @StiensWout in pingdotgg/t3code#5495 * fix(web): clear woke state on explicit thread actions by @StiensWout in pingdotgg/t3code#5486 * fix(server): skip origin fetch when creating worktrees in repos without an origin remote by @t3dotgg in pingdotgg/t3code#5556 * fix(web): update tooltip no longer dismisses when scrolling release notes by @t3dotgg in pingdotgg/t3code#5547 * fix(server): stop showing commit/push/PR notices as errors in the work log by @t3dotgg in pingdotgg/t3code#5559 * fix(web): show remote environment for non-Git projects by @t3dotgg in pingdotgg/t3code#5555 * fix(server): stopping a Claude thread no longer shows an ede_diagnostic error by @t3dotgg in pingdotgg/t3code#5557 * fix(web): show one toast when snoozing threads in bulk by @t3dotgg in pingdotgg/t3code#5560 * fix(server): let stopped threads settle immediately by @t3dotgg in pingdotgg/t3code#5553 * feat: paginate thread loading with user-anchored turn windows by @t3dotgg in pingdotgg/t3code#5493 * fix: prevent reconnect loops during server stalls by @gfsaaser24 in pingdotgg/t3code#5561 * fix(server): settle stopped Claude subagents by @t3dotgg in pingdotgg/t3code#5568 * fix: scrolling up during a running thread no longer snaps back to the bottom by @t3dotgg in pingdotgg/t3code#5566 * fix(server): one disconnecting client no longer blocks every reconnect by @t3dotgg in pingdotgg/t3code#5572 * test(server): catch client transfer regressions in CI by @t3dotgg in pingdotgg/t3code#5350 * fix(web): stop the "requests are slow" warning from firing on every provider update by @t3dotgg in pingdotgg/t3code#5570 * fix(web): keep agent panel rows stable by @t3dotgg in pingdotgg/t3code#5569 * docs: ship production T3 Connect public config in .env.example by @t3dotgg in pingdotgg/t3code#5573 * fix(web): plans stop hijacking the UI, fold into chat instead by @t3dotgg in pingdotgg/t3code#5558 * feat(web): remove Build/Plan toggle from the composer by @t3dotgg in pingdotgg/t3code#5551 * feat(web): per-device provider settings by @t3dotgg in pingdotgg/t3code#4479 * fix(mobile): invisible T3 Connect devices can now be seen and removed by @t3dotgg in pingdotgg/t3code#5563 * fix: add missing space before 'GitHub releases page' link on download page by @Mateleo in pingdotgg/t3code#4511 * fix(web): stop the sidebar "Working" label from pulsing by @t3dotgg in pingdotgg/t3code#5580 * feat(web): add modular theme library by @StiensWout in pingdotgg/t3code#5226 * fix(web): reading a thread clears Done; Woke is dismissible by @t3dotgg in pingdotgg/t3code#5579 * perf(dev): faster cold-start for dev web serving by @t3dotgg in pingdotgg/t3code#5584 * fix(dev): agents get --share right on the first try by @t3dotgg in pingdotgg/t3code#5586 * fix(mobile): improve keyboard avoiding by @jmeistrich in pingdotgg/t3code#5451 * fix(web): live background-work banner no longer hides behind the update notice by @t3dotgg in pingdotgg/t3code#5595 * fix(web): stabilize chat timeline positioning by @jmeistrich in pingdotgg/t3code#5449 * feat(server): record runtime mode per turn and on mode changes by @t3dotgg in pingdotgg/t3code#5593 * feat(web): thread actions from the chat header title by @t3dotgg in pingdotgg/t3code#5592 * fix(mobile): avoid iOS terminal reset on clear by @justynleung in pingdotgg/t3code#5440 * fix(mobile): pad scroll views above Android nav bar by @StoneCotton in pingdotgg/t3code#5415 * fix(mobile): keep Android chat text from showing through the composer by @PollyGlot in pingdotgg/t3code#5582 * fix(mobile): repair Clerk auth navigation headers by @gabrielelpidio in pingdotgg/t3code#5140 * Bump mobile app version to 1.0.2 by @juliusmarminge in pingdotgg/t3code#5588 * feat(web): click the pin icon to unpin a thread by @UtkarshUsername in pingdotgg/t3code#5578 * fix(web): show the correctly matching shortcut in new thread button's tooltip by @UtkarshUsername in pingdotgg/t3code#5594 ## New Contributors * @gabrielelpidio made their first contribution in pingdotgg/t3code#4874 * @arhxam made their first contribution in pingdotgg/t3code#5027 * @skjiisa made their first contribution in pingdotgg/t3code#4929 * @Lucenx9 made their first contribution in pingdotgg/t3code#4990 * @MaxAnderson95 made their first contribution in pingdotgg/t3code#4895 * @t3-code[bot] made their first contribution in pingdotgg/t3code#5202 * @Brechard made their first contribution in pingdotgg/t3code#5327 * @naMqe-h made their first contribution in pingdotgg/t3code#5326 * @Bil0000 made their first contribution in pingdotgg/t3code#5353 * @gfsaaser24 made their first contribution in pingdotgg/t3code#5561 * @Mateleo made their first contribution in pingdotgg/t3code#4511 * @jmeistrich made their first contribution in pingdotgg/t3code#5451 * @justynleung made their first contribution in pingdotgg/t3code#5440 * @StoneCotton made their first contribution in pingdotgg/t3code#5415 * @PollyGlot made their first contribution in pingdotgg/t3code#5582 **Full Changelog**: pingdotgg/t3code@v0.0.31...v0.0.32 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.32
What Changed
ServerProviders(packages/contracts/src/server.ts) wasSchema.Array(ServerProvider). This wraps it inForwardCompatibleArray— the same helper #5055 introduced forServerConfigIssuesandavailableEditors— so a provider element this build can't decode is dropped instead of failing the whole array.Adds one test alongside the existing forward-compat tests in
server.test.ts: an array with one decodable provider and one with an unknownstatusdecodes to just the first.Why
ServerProviderhas several nested literal-union status fields:ServerProviderState,ServerProviderAuthStatus,ServerProviderVersionAdvisoryStatus,ServerProviderUpdateStatus. Adding a new member to any of them — which happens whenever provider status/update features grow — makes an older client's entireprovidersarray fail to decode. Sinceproviderslives insideServerConfig, that failure isn't scoped to the provider list:ServerConfigdecodes as one atomic unit, andserver.getConfigis the client's initial-sync gate on every WebSocket connection (packages/client-runtime/src/rpc/session.ts). One unrecognized provider status takes down the whole config decode, which the client can't distinguish from a transport error, and it retries forever.I hit this from a different angle (a downstream fork added editor ids that don't exist upstream, which failed
availableEditorsdecode the same way#5055already covers) and noticedServerProviderswas the one array left on the un-wrappedSchema.Arrayfrom that same PR. Since provider status enums are the field most likely to grow next, it seemed worth closing before it bites a real client version-skew case — an older mobile/desktop build against a server that shipped a new provider status.UI Changes
None.
Checklist
vp test runinpackages/contracts, plus full workspacevp run -r typecheck)Note
Low Risk
Contract decoding behavior change in contracts only; aligns with existing forward-compat patterns and reduces version-skew connection failures.
Overview
ServerProvidersnow usesForwardCompatibleArray(ServerProvider)instead of a plainSchema.Array, matchingavailableEditorsandServerConfigIssues.When the server sends a provider snapshot this build cannot decode (e.g. a new
statusliteral), that element is dropped instead of failing the entireprovidersarray andServerConfigdecode on initial WebSocket sync.A test in
server.test.tsasserts a mix of valid and unknown-status providers decodes to only the recognizable entry.Reviewed by Cursor Bugbot for commit dc16ad8. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Decode
ServerProvidersforward-compatibly by dropping unknown entriesChanges
ServerProvidersin server.ts fromSchema.Array(ServerProvider)toForwardCompatibleArray(ServerProvider). This makes decoding tolerant of unknown provider status kinds — entries that cannot be decoded are silently dropped instead of failing the entire array.Macroscope summarized dc16ad8.