Every start logged, and still logs on the current image:
/usr/local/bin/docker-entrypoint.sh: 149: /usr/local/bin/dsh-workspace-doctor: not found
dsh-entrypoint: workspace doctor: see the report above - set DSH_WORKSPACE_DOCTOR=repair to fix it at startup
The doctor was installed (/usr/local/bin/dsh-workspace-doctor.mjs), but the entrypoint invoked it without the .mjs extension, so it never ran: no report, no repair. CI stayed green because the smoke test checked the .mjs path with a direct docker exec, which cannot see a mistake in the entrypoint's own invocation.
Fix
Resolve the doctor by name (command -v dsh-workspace-doctor.mjs) in both the root and the non-root path, so the installed file name is the single source of truth.
When it cannot be found, log an explicit workspace doctor: dsh-workspace-doctor.mjs is not installed in this image line instead of the shell's bare not found, and continue the boot (never block a start).
Smoke test now reads the container's boot log: it requires the doctor's own dsh-workspace-doctor: output, and fails the build if the entrypoint logs its workspace doctor: failure line. That asserts path + exec bit + invocation together.
README: manual repair via a one-off container with --entrypoint while dsh is stopped, and a note that an existing Unraid container does not pick up a template variable it gained later.
Verification
The real entrypoint was run end to end (non-root path) with the doctor on PATH: it reports and then execs dsh; with the binary hidden from PATH it degrades with the explicit message and still starts dsh.
The root branch's block was extracted verbatim and run in warn / repair modes with the binary present and absent: repair re-accounts the sessions, backups are written, and the missing-binary path logs and continues.
Static cross-check between the name the entrypoint resolves and the name the Dockerfile installs: match.
YAML parses, sh -n clean on the entrypoint and on the CI build_one() subshell.
Note for the maintainer: the running container still holds the pre-repair registry in memory, so the repair behaviour only shows up after a restart on an image built with this fix.
## Symptom
Every start logged, and still logs on the current image:
```
/usr/local/bin/docker-entrypoint.sh: 149: /usr/local/bin/dsh-workspace-doctor: not found
dsh-entrypoint: workspace doctor: see the report above - set DSH_WORKSPACE_DOCTOR=repair to fix it at startup
```
The doctor was installed (`/usr/local/bin/dsh-workspace-doctor.mjs`), but the entrypoint invoked it without the `.mjs` extension, so it never ran: no report, no repair. CI stayed green because the smoke test checked the `.mjs` path with a direct `docker exec`, which cannot see a mistake in the entrypoint's own invocation.
## Fix
- Resolve the doctor by name (`command -v dsh-workspace-doctor.mjs`) in both the root and the non-root path, so the installed file name is the single source of truth.
- When it cannot be found, log an explicit `workspace doctor: dsh-workspace-doctor.mjs is not installed in this image` line instead of the shell's bare `not found`, and continue the boot (never block a start).
- Smoke test now reads the container's boot log: it requires the doctor's own `dsh-workspace-doctor:` output, and fails the build if the entrypoint logs its `workspace doctor:` failure line. That asserts path + exec bit + invocation together.
- README: manual repair via a one-off container with `--entrypoint` while dsh is stopped, and a note that an existing Unraid container does not pick up a template variable it gained later.
## Verification
- The real entrypoint was run end to end (non-root path) with the doctor on PATH: it reports and then execs dsh; with the binary hidden from PATH it degrades with the explicit message and still starts dsh.
- The root branch's block was extracted verbatim and run in `warn` / `repair` modes with the binary present and absent: repair re-accounts the sessions, backups are written, and the missing-binary path logs and continues.
- Static cross-check between the name the entrypoint resolves and the name the Dockerfile installs: match.
- YAML parses, `sh -n` clean on the entrypoint and on the CI `build_one()` subshell.
Note for the maintainer: the running container still holds the pre-repair registry in memory, so the `repair` behaviour only shows up after a restart on an image built with this fix.
The entrypoint called /usr/local/bin/dsh-workspace-doctor while the
Dockerfile installs /usr/local/bin/dsh-workspace-doctor.mjs, so every
start logged "...: not found" and the workspace doctor never ran: no
report, no repair. The CI smoke test checked the .mjs path with a direct
`docker exec`, which cannot see a mistake in the entrypoint's own
invocation, so the build stayed green while the container was broken.
Resolve the doctor by name (`command -v dsh-workspace-doctor.mjs`) in
both the root and the non-root path, and log an explicit "not installed
in this image" line when it cannot be found, instead of the shell's bare
"not found". The smoke test now reads the container's boot log: it
requires the doctor's own "dsh-workspace-doctor:" output to appear, and
fails if the entrypoint logs its "workspace doctor:" failure line — that
covers path, exec bit and invocation together, which is the class of
mistake that shipped.
README: manual repair through a one-off container with --entrypoint (dsh
stopped, so nothing races the registry write), and the note that an
existing Unraid container does not pick up the template's new Workspace
Doctor variable on its own.
mward4
merged commit 3849709cc2 into main2026-09-17 22:22:11 -04:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Symptom
Every start logged, and still logs on the current image:
The doctor was installed (
/usr/local/bin/dsh-workspace-doctor.mjs), but the entrypoint invoked it without the.mjsextension, so it never ran: no report, no repair. CI stayed green because the smoke test checked the.mjspath with a directdocker exec, which cannot see a mistake in the entrypoint's own invocation.Fix
command -v dsh-workspace-doctor.mjs) in both the root and the non-root path, so the installed file name is the single source of truth.workspace doctor: dsh-workspace-doctor.mjs is not installed in this imageline instead of the shell's barenot found, and continue the boot (never block a start).dsh-workspace-doctor:output, and fails the build if the entrypoint logs itsworkspace doctor:failure line. That asserts path + exec bit + invocation together.--entrypointwhile dsh is stopped, and a note that an existing Unraid container does not pick up a template variable it gained later.Verification
warn/repairmodes with the binary present and absent: repair re-accounts the sessions, backups are written, and the missing-binary path logs and continues.sh -nclean on the entrypoint and on the CIbuild_one()subshell.Note for the maintainer: the running container still holds the pre-repair registry in memory, so the
repairbehaviour only shows up after a restart on an image built with this fix.