resolve a relative task cwd against the user's home before spawning

the file browser sends msg.cwd relative to the user's home and it went straight to
Bun.spawn, which resolves it against the server's cwd. when that directory does not
exist posix_spawn reports ENOENT naming the binary rather than the directory, so
"Convert Audio" failed with the misleading "posix_spawn 'bash'".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-16 00:38:12 +00:00
co-authored by Claude Opus 4.8
parent 7d8341d3ba
commit 1ed12cd3ba
2 changed files with 4 additions and 10 deletions
-7
View File
@@ -27,13 +27,6 @@ Deferred work. Context: Officer is collapsing from multi-tenant / open-source-re
## Known bugs
- [ ] **Convert Audio task fails with `ENOENT: posix_spawn 'bash'`.** Misleading error — the real
cause is a *relative* `cwd` passed to `Bun.spawn` (ENOENT fires when the child's cwd doesn't
exist, not when the binary is missing). Fix is in `api/tasks/task-executor.ts`: resolve
`msg.cwd` against the user's home when it isn't absolute
(`isAbsolute(msg.cwd) ? msg.cwd : join(homeDir, msg.cwd)`). Was written and verified once, then
discarded in a working-tree cleanup.
- [ ] **`bootstrap.ts` runs `npm install -g` for Pi on every boot.** `findPiPackageDir` checks stale
paths and an outdated package name, so `installPi` always fires and floods the logs with
`EEXIST` noise. Should detect `@earendil-works/pi-coding-agent` at the real npm prefix.
+4 -3
View File
@@ -1,5 +1,5 @@
import type { ServerWebSocket } from 'bun';
import { join } from 'node:path';
import { join, isAbsolute } from 'node:path';
import { mkdirSync, writeFileSync, chmodSync, rmSync } from 'node:fs';
import { getTaskByDirName } from 'officerdb';
import { getHomeDirForRole, DATA_PATH } from '../../data-path';
@@ -124,9 +124,10 @@ async function handleRun(ws: ServerWebSocket<WSData>, msg: RunMessage) {
const runner = getRunner(language);
const cmd = [...runner, scriptPath, ...positionalArgs];
// Resolve cwd
// msg.cwd arrives from the file browser relative to the user's home; Bun.spawn needs it absolute
// (a missing cwd surfaces as ENOENT naming the binary, not the directory)
const homeDir = getHomeDirForRole(email, role);
const cwd = msg.cwd ?? homeDir;
const cwd = msg.cwd ? (isAbsolute(msg.cwd) ? msg.cwd : join(homeDir, msg.cwd)) : homeDir;
let spawnCmd: string[];
let spawnEnv: Record<string, string>;