Skip to content

fix(tools): validate per-call workdir and preserve resolved TERMINAL_CWD#4731

Closed
HenkDz wants to merge 1 commit into
NousResearch:mainfrom
HenkDz:fix/terminal-cwd-validation
Closed

fix(tools): validate per-call workdir and preserve resolved TERMINAL_CWD#4731
HenkDz wants to merge 1 commit into
NousResearch:mainfrom
HenkDz:fix/terminal-cwd-validation

Conversation

@HenkDz

@HenkDz HenkDz commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Fixes #4669 and #4672.

Summary

Two related bugs where terminal.cwd gets silently overridden by downstream code that doesn't validate/resolve the path properly.

#4672 — gateway/run.py clobbers resolved TERMINAL_CWD

cli.py resolves terminal.cwd: "." to os.getcwd() at import time, but gateway/run.py re-bridges the config and sets TERMINAL_CWD = "." (raw string) when imported as a plugin. This overwrites the absolute path, and later code falls back to Path.home().

Fix: Skip the cwd key in gateway's terminal env bridge when TERMINAL_CWD is already an absolute path.

#4669 — terminal tool passes invalid workdir to Docker exec

When a per-call workdir is provided but invalid (e.g. /workspace/..???), it gets passed straight to docker exec -w <invalid-path>, causing silent command failures. This makes it look like Docker is ignoring terminal.cwd, but the real problem is that invalid per-call workdir overrides the session cwd without validation.

Fix: Validate workdir before passing to env.execute(). If the path is malformed or relative (ambiguous in container backends), fall back to the session cwd with a warning log.

Changes

  • gateway/run.py — skip clobbering already-resolved TERMINAL_CWD
  • tools/terminal_tool.py — validate workdir, fall back to session cwd if invalid

Fixes NousResearch#4669 and NousResearch#4672.

- gateway/run.py: skip re-bridging cwd config key when TERMINAL_CWD is
  already an absolute path (cli.py resolved it from '.'). Without this,
  gateway overwrites the resolved path with raw '.' and falls back to
  Path.home().

- tools/terminal_tool.py: validate workdir before passing to env.execute().
  Malformed paths (e.g. '/workspace/..???') are silently passed through
  to 'docker exec -w', causing command failures that look like Docker is
  ignoring terminal.cwd. Now falls back to session cwd with a warning.
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the thorough diagnosis, @HenkDz! Both bugs this PR targets have since been fixed on main by independent commits — this is an automated hermes-sweeper review.

Bug #4672 — TERMINAL_CWD clobber in gateway/run.py

Fixed in commit 3c42064e (PR #11029, merged Apr 16 2026): gateway/run.py lines 150–154 now skip placeholder cwd values (".", "auto", "cwd") in the config bridge, so an already-resolved absolute TERMINAL_CWD set by cli.py is never overwritten.

Bug #4669 — invalid workdir forwarded to docker exec

Fixed in commit af9a9f77 (salvage of PR #5620, merged Apr 6 2026): _validate_workdir() (character allowlist) was added to tools/terminal_tool.py and shlex.quote() hardening was added at every backend interpolation point. Invalid/malformed workdir values are now blocked before reaching env.execute()exit_code: -1 with status: blocked rather than silently failing inside the container.

Note: the behavior on main is to block and error on an invalid workdir rather than fall back to session cwd as this PR proposed. If you have a use-case where silent fallback is preferable to an explicit error, feel free to open a new PR or comment on the linked issues.

@teknium1 teknium1 closed this Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: terminal tool passes invalid workdir to Docker exec and overrides configured terminal.cwd

3 participants