zai-org / zai-org/feedback

[Bug] Model picker empty in WSL remote projects after server restart (account/plan state never re-synced)[Bug]

Open
#681 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2 status: 待评估 type: Bug
Dominant language
No language data
Stars
22
Forks
1
PR merge metrics
No merged PRs in 30d

Description

提交前确认 · Pre-submission checklist
  • 我已搜索过现有 issue,确认这不是重复 / I searched existing issues and confirmed this isn't a duplicate.
  • 我已阅读 CONTRIBUTING.md / I've read CONTRIBUTING.md.
问题类别 · Category

账号 / 登录 · Account / Login

涉及的 Agent 框架 · Agent framework

ZCode Agent(自研)

严重程度 · Severity

阻塞使用 · Blocking (无法使用核心功能 / core function unusable)

复现频率 · Reproducibility

必现 · Always

问题描述 · Description

Environment

  • OS: Windows 11 (build 26200), ZCode desktop 3.12.2
  • Remote: WSL2, distro Ubuntu-20.04, project opened as remote workspace (remote:wsl:Ubuntu-20.04:/home/marcelo/...)
  • Network: USB 4G modem (relevant only to the timeline below; the picker bug reproduces with fully working WSL networking)
  • No proxy/VPN active during the repro steps below (Tailscale installed but stopped).

Summary

When opening a WSL project, the model picker shows only "Manage" — no models are listed and none can be selected. Local (Windows) projects in the same app instance work perfectly with the same account (GLM-5.3, zai individual coding plan).

The key observation: the picker worked at one point while a long-lived WSL protocol server process (started before I logged in on the Windows side) held the account/plan state in memory. After every wsl --shutdown or app restart, freshly started WSL servers never receive the account/plan state again, so the picker stays empty even though:

  • WSL has internet access (verified: https://api.z.ai returns 200 in ~1s from inside WSL)
  • ~/.zcode/v2/credentials.json inside WSL exists and is fresh (written by the app itself during the working window)
  • ~/.zcode/v2/coding-plan-cache.json inside WSL reports builtin:zai-coding-plan: available
  • ~/.zcode/v2/setting.json inside WSL has the correct selection (modelProviderFamilySelectedKeys.zai = "coding-plan:builtin:zai-coding-plan", identical to the Windows side)
复现步骤 · Steps to reproduce

Steps to reproduce

  1. Windows app 3.12.2, logged in with a zai coding plan. Open a WSL remote project and confirm the model picker works.
  2. Run wsl --shutdown (or fully restart the ZCode app).
  3. Reopen the same WSL project in the app.
  4. Model picker shows only "Manage"; no models selectable.

Evidence

1. Model selection persistence fails with a database FK error (Windows-side log, ~/.zcode/cli/log/zcode-2026-09-16.jsonl):

{"level":"warn","event":"session.model_selection.persist_failed",
 "message":"Session model selection persistence failed",
 "context":{"error":"FOREIGN KEY constraint failed",
            "modelId":"GLM-5.3","providerId":"account:zai-individual-coding-plan",
            "thoughtLevel":"low"}}

The failing sessions (sess_3b8c40f2…, sess_ba775482…) do not exist as rows in the session table of either ~/.zcode/cli/db/db.sqlite (Windows) or the WSL-side DB — the session row was never persisted (session_create logged with "persistence":"deferred"), so dependent inserts fail the FK.

2. Provider registry divergence between Windows and WSL. The zcode_protocol.provider_registry.ready event carries a different accountRevision hash on each side:

  • Windows: zcode-builtin:28:9cd1cc2f4a86…
  • WSL: zcode-builtin:28:ac6ecccf22e18… (all account providers entitled:false; plan entitlement from the coding-plan cache is apparently never merged in)

3. No account/plan/subscription fetch attempts at all on the WSL side after server startup. Scanning the WSL-side log after a fresh server start shows zero events matching plan/subscription/entitlement/account — the server never even tries to refresh the plan state.

4. Server redeploy is byte-identical. Deleting ~/.zcode/server/ and letting the app re-deploy produces the exact same zcode-server.cjs (same size and timestamp), ruling out a stale-server-version theory.

What did NOT fix it

  • Full app restart / killing all zcode processes
  • Removing and letting the app re-deploy the WSL server bundle
  • Removing and restoring credentials.json in WSL (the app does not re-push it on its own after a fresh server start; the only time it was written was during the original login flow while the then-running server was alive)
  • Switching WSL to networkingMode=mirrored (fixed a separate NAT issue with the 4G modem, but the picker remains empty)
  • Uninstalling an old standalone ZCode .deb (3.7.7) that was previously installed inside WSL
期望表现 · Expected behavior

Workaround / expected behavior

Expected: after any WSL server restart, the app re-syncs the account/plan state to the WSL server (or the server fetches it using the stored credentials), and the model picker populates.

Actual: the picker only ever worked on a server process that happened to be alive across the Windows-side login event.

Timeline (2026-09-16, local UTC-3)

  • 11:59 — WSL protocol server starts (pre-login state)
  • ~13:28 — Login on Windows side; credentials.json in WSL written; account state reaches the running WSL server (in memory)
  • 15:22 — Model picker works in WSL project; a message sent to GLM-5.3 fails with network errors (unrelated: WSL2 NAT broken with USB 4G modem — fixed separately)
  • 15:33+ — wsl --shutdown (multiple times, for the NAT fix), app restarts
  • Since then — every fresh WSL server start leaves the model picker empty; evidence above collected across these restarts

Happy to provide full sanitized logs, setting.json dumps, or DB schema details if useful.

实际表现 · Actual behavior

When opening a WSL remote project, the model picker shows only "Manage" — the model list is completely empty and no model can be selected. Local Windows projects in the same app instance, with the same account, list and use models normally (GLM-5.3, zai individual coding plan).

This happens on every freshly started WSL zcode-server, even though all state on the WSL side is valid:

  • internet access from WSL verified (api.z.ai returns 200 in ~1s)
  • ~/.zcode/v2/credentials.json present and fresh (written by the app itself)
  • ~/.zcode/v2/coding-plan-cache.json reports builtin:zai-coding-plan: "available"
  • ~/.zcode/v2/setting.json has the same modelProviderFamilySelectedKeys value as the Windows side

The only time the picker worked was on a WSL server process that had been started BEFORE I logged in on the Windows side, i.e. it received the account/plan state in memory during the login flow. After any wsl --shutdown or app restart, freshly started WSL servers never receive the plan state again: the WSL-side log shows zero plan/subscription/entitlement fetch attempts after startup, and the provider registry accountRevision hash differs between Windows (zcode-builtin:28:9cd1cc2f...) and WSL (zcode-builtin:28:ac6ecccf...).

Additionally, when a model selection is attempted, persistence fails with:
event: session.model_selection.persist_failed, error: "FOREIGN KEY constraint failed" (modelId GLM-5.3, providerId account:zai-individual-coding-plan) — the referenced session row was never inserted into ~/.zcode/cli/db/db.sqlite on either side (session_create logged with "persistence": "deferred").

ZCode 版本 · ZCode version

3.12.2

设备 / 系统 / 浏览器 · Device / OS / Browser

Windows / WSL

截图 / 录屏 / 日志 · Screenshots / Recordings / Logs

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with fresh WSL server startup and the WSL-side protocol log, then compare provider_registry.ready accountRevision values with the Windows side. Inspect ~/.zcode/server/zcode-server.cjs, credentials.json, coding-plan-cache.json, and the CLI db.sqlite evidence around account/plan synchronization and deferred session creation. Done means a restarted WSL server repopulates the model picker and model selection no longer fails with a foreign-key error.

Written by the indexing model from the issue text.

Assessment

Tech stack
sqlite, ubuntu
Domain
authentication, database, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.