Repository navigation
[Bug] proxy disable leaves daemon worker running when runtime metadata is missing, blocking WebDAV restore #497
Description
Summary
On Linux with cc-switch 5.11.0, cc-switch --app codex proxy disable reports success but leaves the daemon-managed Codex worker running when the proxy_runtime_session setting is absent. This leaves the app in a state where all takeover flags are false but the proxy still listens on 127.0.0.1:15722, and WebDAV snapshot restore is blocked.
This was reproduced against the installed binary in the existing faulty state. The initial cause of the missing runtime metadata has not been established.
Environment
- CC Switch CLI:
cc-switch 5.11.0 - OS: Linux x86_64, kernel
5.15.0-43-generic - Proxy mode: daemon-managed Codex worker on
127.0.0.1:15722 - Claude, Codex and Gemini takeover flags: all false
- Auto-failover: disabled for all three apps
- WebDAV: configured; automatic cloud sync disabled
Observed state and reproduction
Before attempting to disable the route, a read-only SQLite inspection confirmed:
SELECT COUNT(*) FROM settings WHERE key = 'proxy_runtime_session';
-- 0
SELECT COUNT(*) FROM proxy_config WHERE live_takeover_active != 0;
-- 0At the same time, cc-switch daemon status showed a live worker:
worker: running at 127.0.0.1:15722 (pid 133226)
worker[codex]: 127.0.0.1:15722 (pid 133226)
takeovers: claude=false, codex=false, gemini=false
restart count: 0
-
In this state, run:
cc-switch --app codex proxy disable
-
The command exits successfully and prints:
代理路由 codex: 关闭 -
Run
cc-switch daemon statusand inspect the listener:ss -ltnp '( sport = :15722 )'The same worker PID
133226remains running and listening. All three takeover flags remain false. -
WebDAV download/restore reports:
WebDAV 下载失败:本地代理正在运行,请先停止代理后再执行云同步恢复 (The local proxy is running. Stop it before restoring a cloud-sync snapshot.)
No database record was manually deleted to create this live reproduction; the missing record was found during diagnosis. Repeating this in a test should use an isolated database and daemon/socket environment rather than editing a production database.
Expected behavior
Disabling the Codex route should stop its daemon-managed worker even if the persisted runtime session record is missing or stale, or return an explicit failure if it cannot stop the worker. Other applications' workers should remain unaffected.
The WebDAV restore guard should continue to reject restoration while a proxy really is running; bypassing that guard would not fix the lifecycle problem.
Suspected code path
Source inspected at the v5.11.0 commit b781987413279ccca6102ef0ad2a283fe364b566:
should_drop_takeover_via_daemonreturnsfalseimmediately when the persisted session for the app is absent. It checks for an unreachable socket but does not consult a reachable daemon's worker state in this branch.set_managed_session_for_app_unlockedconsequently chooses local cleanup instead of sendingDropTakeoverto the daemon.local_disable_takeoveralso requires a persisted session to find and terminate the worker, so it can return success after configuration cleanup while the worker remains alive.- In contrast,
get_status_with_cleanup_for_appfalls back to the daemon when persisted metadata is absent, so the running worker is still detected by the WebDAV restore guard.
Please consider checking authoritative daemon state before taking the local-only disable path when runtime metadata is absent or unusable. A regression test could cover a reachable daemon with a live worker, missing proxy_runtime_session, and cleared takeover flags, then assert that per-app disable actually stops that worker.
Workaround and remaining unknowns
cc-switch daemon stop successfully stopped the daemon and worker. The listener disappeared and cc-switch proxy show reported that the proxy was no longer running. This stops all daemon-managed workers, so it is broader than per-app disable.
Earlier in the same session, a successful daemon stop was followed 48 seconds later by a new daemon and Codex worker. The log explicitly classified the old worker's exit as expected, with no restart; the later worker belonged to a newly started daemon. The specific UI action that started the new daemon and the cause of the missing metadata are still unknown. There is no evidence that WebDAV download itself starts the proxy.
Related lifecycle tracking: #192. This report concerns the concrete missing-metadata disable failure.
Activity
SaladDay commentedon Oct 12, 2026
Fixed in #508. Disabling an app now asks the daemon to stop its worker even when runtime metadata is missing or stale, without stopping other apps.
Thanks for the detailed report! This will be included in the next release.