jsh cannot determine current directory after cwd becomes unavailable #95

Open
opened 2026-09-22 18:04:11 -04:00 by ober · 0 comments
Owner

Problem

jsh can fail with:

jsh: cannot determine current directory

This blocks an otherwise valid command from running. The observed command was:

jd sync -v -d . jd:mac2/ 2>&1 | tail

The prompt showed user@localhost:~, but jsh still reported that it could not determine the current directory.

Environment

  • macOS arm64
  • Shell executable: /Users/user/.local/bin/jsh
  • SHELL=/Users/user/.local/bin/jsh
  • jd is a small wrapper that sets the user's drive/profile environment and executes jdrive s3 "$@"; the vault password value is intentionally omitted here.
  • The installed jdrive binary was separately found to contain a stale embedded version string (2.0.18 while the repository version was newer). That was corrected independently; it does not explain this jsh error.

Minimal reproduction

The failure is reproducible when a process starts with a directory that has been removed:

tmpdir=$(mktemp -d /tmp/jsh-cwd-repro.XXXXXX)
outfile=$(mktemp /tmp/jsh-cwd-output.XXXXXX)
(
  cd "$tmpdir" || exit 1
  /Users/user/.local/bin/jsh -c 'echo jsh-ran'
) >"$outfile" 2>&1 &
pid=$!
sleep 0.05
rmdir "$tmpdir"
wait "$pid"
cat "$outfile"

Observed output:

Exception in current-directory: cannot determine current directory

The process exits nonzero and does not execute echo jsh-ran.

By contrast, from a valid directory:

/Users/user/.local/bin/jsh -c 'pwd; echo direct-jsh-ok'

works normally.

The jsh binary also contains the related diagnostic text:

failed to get current working directory:
did your CWD get deleted?

What has been ruled out

  • This is not caused by the S3 endpoint or remote object path; the shell/runtime error occurs before sync can proceed.
  • Rebuilding jerboa-drive changes its version output but does not remove the jsh failure.
  • /Users/user/.local/bin/jdrive version succeeds even when launched from a deleted cwd, so this is specific to a path that asks the runtime for the current directory (or to shell command startup), not a universal inability to execute the binary.

Possible fixes

  1. Make the current-directory primitive return a structured, actionable error for getcwd() failures, including the underlying errno (ENOENT, EACCES, etc.) and the likely recovery (cd to an existing directory or restart the shell).
  2. Add a shell-level recovery path for a deleted cwd. A safe default is to keep the shell alive and allow cd / or cd "$HOME"; silently changing the cwd is probably surprising and should not happen without an explicit user action.
  3. Where command execution only needs to preserve a relative path such as ., avoid eagerly resolving it through getcwd() if the shell can pass it unchanged. If an absolute path is required, use a validated PWD fallback only with clear safeguards because PWD may be stale or attacker-controlled.
  4. Normalize the diagnostic so interactive users consistently see the failing operation and errno rather than only jsh: cannot determine current directory.
  5. Add regression coverage that launches jsh from a directory removed after chdir(), verifies the current error, and verifies the intended recovery behavior. Also cover inaccessible cwd and symlinked cwd cases.

Requested outcome

Please confirm whether this is expected behavior for a deleted/inaccessible cwd and implement the safest recovery/diagnostic behavior. The immediate user impact is that a shell session can look healthy while every command that consults the current directory fails.

## Problem `jsh` can fail with: ```text jsh: cannot determine current directory ``` This blocks an otherwise valid command from running. The observed command was: ```sh jd sync -v -d . jd:mac2/ 2>&1 | tail ``` The prompt showed `user@localhost:~`, but `jsh` still reported that it could not determine the current directory. ## Environment - macOS arm64 - Shell executable: `/Users/user/.local/bin/jsh` - `SHELL=/Users/user/.local/bin/jsh` - `jd` is a small wrapper that sets the user's drive/profile environment and executes `jdrive s3 "$@"`; the vault password value is intentionally omitted here. - The installed `jdrive` binary was separately found to contain a stale embedded version string (`2.0.18` while the repository version was newer). That was corrected independently; it does not explain this `jsh` error. ## Minimal reproduction The failure is reproducible when a process starts with a directory that has been removed: ```sh tmpdir=$(mktemp -d /tmp/jsh-cwd-repro.XXXXXX) outfile=$(mktemp /tmp/jsh-cwd-output.XXXXXX) ( cd "$tmpdir" || exit 1 /Users/user/.local/bin/jsh -c 'echo jsh-ran' ) >"$outfile" 2>&1 & pid=$! sleep 0.05 rmdir "$tmpdir" wait "$pid" cat "$outfile" ``` Observed output: ```text Exception in current-directory: cannot determine current directory ``` The process exits nonzero and does not execute `echo jsh-ran`. By contrast, from a valid directory: ```sh /Users/user/.local/bin/jsh -c 'pwd; echo direct-jsh-ok' ``` works normally. The `jsh` binary also contains the related diagnostic text: ```text failed to get current working directory: did your CWD get deleted? ``` ## What has been ruled out - This is not caused by the S3 endpoint or remote object path; the shell/runtime error occurs before sync can proceed. - Rebuilding `jerboa-drive` changes its version output but does not remove the `jsh` failure. - `/Users/user/.local/bin/jdrive version` succeeds even when launched from a deleted cwd, so this is specific to a path that asks the runtime for the current directory (or to shell command startup), not a universal inability to execute the binary. ## Possible fixes 1. Make the `current-directory` primitive return a structured, actionable error for `getcwd()` failures, including the underlying errno (`ENOENT`, `EACCES`, etc.) and the likely recovery (`cd` to an existing directory or restart the shell). 2. Add a shell-level recovery path for a deleted cwd. A safe default is to keep the shell alive and allow `cd /` or `cd "$HOME"`; silently changing the cwd is probably surprising and should not happen without an explicit user action. 3. Where command execution only needs to preserve a relative path such as `.`, avoid eagerly resolving it through `getcwd()` if the shell can pass it unchanged. If an absolute path is required, use a validated `PWD` fallback only with clear safeguards because `PWD` may be stale or attacker-controlled. 4. Normalize the diagnostic so interactive users consistently see the failing operation and errno rather than only `jsh: cannot determine current directory`. 5. Add regression coverage that launches `jsh` from a directory removed after `chdir()`, verifies the current error, and verifies the intended recovery behavior. Also cover inaccessible cwd and symlinked cwd cases. ## Requested outcome Please confirm whether this is expected behavior for a deleted/inaccessible cwd and implement the safest recovery/diagnostic behavior. The immediate user impact is that a shell session can look healthy while every command that consults the current directory fails.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ober/jerboa-shell#95
No description provided.