[Bug] Dashboard self-update loses worker under custom systemd system service
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 28/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- linux, node.js, typescript
Research direction
Start by locating the Dashboard npm update worker, its service ownership detection and restart logic, and the job status handling; the issue does not name source files or tests. Read the v2.93.0 baseline and the staging candidate's synthetic tests, then trace how the actual systemd owner and worker scope are verified. Done means the updater safely refuses unsupported custom system units before package mutation, preserves or reports failure for the job, and has coverage for the stated lifecycle cases; destructive end-to-end certification is still outstanding.
Written by the indexing model from the issue text.
Description
Client or integration
OpenCodex dashboard
Area
Service lifecycle
Summary
A Dashboard-triggered npm self-update can leave OpenCodex unavailable (HTTP 502 from the reverse proxy) on Linux when the running proxy belongs to a system-wide systemd service under an unprivileged UID, rather than the canonical systemd user service. An update worker may die when the original service's cgroup is stopped; moreover the updater may target a different, installed-but-inactive user unit. The Dashboard job file can remain running with a dead worker PID.
Expected: never stop an active proxy unless a worker can outlive the stop and can restart the actual owner. Unsupported custom system units should receive an actionable, fail-closed error before package mutation.
Reproduction
- Configure a custom root-owned systemd service with
User=<unprivileged-user>,KillMode=control-group,OCX_SERVICE_MANAGED=1, andExecStart=ocx start --port 10101. Keep an OpenCodex-managedsystemctl --userservice installed but inactive. - With OpenCodex v2.89.0 running under the system unit, start a v2.93.0 npm update with
restart:truefrom the Dashboard. - During stop/restart, the original proxy disappears and the browser reports 502; the update job can remain
runningeven though its recorded PID is dead. - Non-destructive supporting reproduction under the same UID:
systemd-run --user --scope --quiet --collect -- /usr/bin/truefails withFailed to connect to bus: No medium foundwhen the system service hasINVOCATION_IDbut noXDG_RUNTIME_DIR. Supplying the verified private/run/user/<uid>makes the scope probe exit 0. A test process launched in that scope is shown under/user.slice/.../app.slice/run-*.scope, outside the system unit cgroup. - Distinct installed supervisor state was reproduced:
ocx service status --jsonreports the user unit installed/enabled but running:false, viable:false, while the independent system unit serves HTTP 200.
The full destructive update scenario has not been re-enacted after remediation; do not treat the non-destructive probes alone as a completed E2E certification.
Version
OpenCodex 2.89.0 → 2.93.0; source baseline v2.93.0 commit 88aaa754566d119b6b8fc898f8fb47602387d82e.
Operating system
Linux, systemd system service + lingered systemd user manager, Bun 1.4.4.
Provider and model
Not provider-specific.
Logs or error output
Failed to connect to bus: No medium found
OWNERSHIP_MUTATION_LEASE_BUSY: another process owns the runtime mutation lease
(recorded PID no longer alive; lease age below stale-reclaim grace period)
systemd: Main process exited, status=1/FAILURE
systemd: Failed to start OpenCodex proxy service
Screenshots and supporting files
The operator captured HTTP 502 Bad gateway during the Dashboard upgrade and a separate startup-safety warning. No screenshots containing private hostnames or identifiers are uploaded here.
Redacted configuration
{
"systemService": {
"type": "systemd system",
"user": "<unprivileged uid>",
"killMode": "control-group",
"managed": true
},
"dashboardUpdate": {
"installer": "npm",
"restart": true
},
"userService": {
"installed": true,
"enabled": true,
"running": false
}
}
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Suggested safety contract
- Identify and attest the actual running supervisor before beginning update.
- Spawn the updater in an independently managed scope with a verified UID-private user-bus socket. Refuse safely if that is impossible.
- Do not target an unrelated user unit when a root-owned custom system unit owns the listener; such a migration needs operator-supervised authorization.
- Record a terminal, actionable
failedstate when the updater PID died; avoid indefiniterunningstatus. - Test service stop, update, restart identity, health stability, rollback and cgroup survival.
A staging-only candidate adds these guards with synthetic tests; it is not deployed or certified.
- Dominant language
- TypeScript
- Stars
- 16.9k
- Forks
- 1.3k
- Avg merge
- 16h 25m
- Merged PRs (30d)
- 706
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from lidge-jun/opencodex
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
lidge-jun/opencodex#7728 · 2 comments ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 25/100
Maintainers usually reply within 1 day
-
bug cli enhancement tools
Difficulty 5/5 Over a week Newbie friendliness 25/100
lidge-jun/opencodex#7963 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 5/5 Over a week Newbie friendliness 35/100
lidge-jun/opencodex#7958 · 1 comment ·
Maintainers usually reply within 1 day
-
Add LLMTR to the free-provider directoryPossibly taken A pull request linked to this issue is open or already merged. Openenhancement provider
Difficulty 3/5 1-2 days Newbie friendliness 28/100
lidge-jun/opencodex#7954 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
All issues in lidge-jun/opencodex
Similar issues
-
Add: Disco Mix SDOpencheck:passed streams:add
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
level2 nsoc26
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
GauravKarakoti/SecureFlow#1488 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
deltachat/deltachat-desktop#6914 ·
Maintainers usually reply within 2 days
-
area:cli bug P4
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
bug from-studio
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
esengine/DeepSeek-Reasonix#14868 ·
Maintainers usually reply within 1 day