CommandMatcher matrix commands fail: Worker script not found (bare-name PATH resolution) #34

Closed
opened 2026-08-21 22:19:29 +00:00 by Mark · 0 comments
Owner

Matrix status bot commands (!runs/!status/!tail/!last-failures) fail on first real exercise — Worker script not found: status-report.py.

Found by: live verification of vikunja#115 (tasker t_322ca763) — first ever command dispatch in the Org Ops room, 2026-08-21 22:09 UTC.

Root cause: src/server/command_matcher.py CommandMatcher.dispatch() runs subprocess.run(script_parts, cwd=self._worker_dir, env=env, ...) with a bare worker name (e.g. status-report.py, no slash) as the command. On POSIX, subprocess resolves a bare name via PATH only — NOT via cwd. /home/b/Projects/org_mode/workers is not on the daemon's PATH (systemd unit PATH: /home/b/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin), so every command dispatch raises FileNotFoundError and is recorded as a failure in the ledger. The webhook/queue path works because AsyncDispatcher uses absolute script paths.

Observed: ledger run 7aed583c-71d7-4d44-8050-6545bd4b43f8 (source=matrix, command status-report.py --runs, status failure, "Worker script not found"); room reply ❌ receipt with the same error.

Fix (hot-deployed on unstable, uncommitted pending this issue): in dispatch(), after building script_parts, absolutize a bare worker name against worker_dir:

# subprocess.run does NOT use cwd for PATH lookup; mirror AsyncDispatcher
# and resolve bare worker names against worker_dir.
if script_parts and "/" not in script_parts[0]:
    resolved = Path(self._worker_dir) / script_parts[0]
    if resolved.exists():
        script_parts[0] = str(resolved)

Deployed via scp + systemctl --user restart org-subscriber.service; post-fix all four commands + failure path verified (ledger success rows 477788c4, 7222fe34, e7909c3b, f35972ce; failure bcaf4342; rich HTML replies in room). See card t_322ca763 report for full evidence.

Acceptance: commit the fix (with a regression note for the matrix-command path) and close this issue; PR review via the normal gating chain.

Refs: vikunja#115, tasker t_322ca763.

Matrix status bot commands (!runs/!status/!tail/!last-failures) fail on first real exercise — `Worker script not found: status-report.py`. **Found by:** live verification of vikunja#115 (tasker t_322ca763) — first ever command dispatch in the Org Ops room, 2026-08-21 22:09 UTC. **Root cause:** `src/server/command_matcher.py` `CommandMatcher.dispatch()` runs `subprocess.run(script_parts, cwd=self._worker_dir, env=env, ...)` with a **bare worker name** (e.g. `status-report.py`, no slash) as the command. On POSIX, subprocess resolves a bare name via PATH only — NOT via cwd. `/home/b/Projects/org_mode/workers` is not on the daemon's PATH (systemd unit PATH: `/home/b/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`), so every command dispatch raises FileNotFoundError and is recorded as a `failure` in the ledger. The webhook/queue path works because AsyncDispatcher uses absolute script paths. **Observed:** ledger run `7aed583c-71d7-4d44-8050-6545bd4b43f8` (source=matrix, command `status-report.py --runs`, status failure, "Worker script not found"); room reply ❌ receipt with the same error. **Fix (hot-deployed on unstable, uncommitted pending this issue):** in `dispatch()`, after building `script_parts`, absolutize a bare worker name against `worker_dir`: ```python # subprocess.run does NOT use cwd for PATH lookup; mirror AsyncDispatcher # and resolve bare worker names against worker_dir. if script_parts and "/" not in script_parts[0]: resolved = Path(self._worker_dir) / script_parts[0] if resolved.exists(): script_parts[0] = str(resolved) ``` Deployed via scp + `systemctl --user restart org-subscriber.service`; post-fix all four commands + failure path verified (ledger success rows `477788c4`, `7222fe34`, `e7909c3b`, `f35972ce`; failure `bcaf4342`; rich HTML replies in room). See card t_322ca763 report for full evidence. **Acceptance:** commit the fix (with a regression note for the matrix-command path) and close this issue; PR review via the normal gating chain. Refs: vikunja#115, tasker t_322ca763.
Mark closed this issue 2026-08-21 22:19:29 +00:00
Sign in to join this conversation.
No description provided.