Skip to content

fix(interactive): avoid nested tokio runtime panic in tab completion#1224

Merged
chaliy merged 2 commits intomainfrom
claude/fix-jq-runtime-error-KuR3Y
Apr 11, 2026
Merged

fix(interactive): avoid nested tokio runtime panic in tab completion#1224
chaliy merged 2 commits intomainfrom
claude/fix-jq-runtime-error-KuR3Y

Conversation

@chaliy
Copy link
Copy Markdown
Contributor

@chaliy chaliy commented Apr 11, 2026

Summary

  • Fix complete_path() calling handle.block_on() from within the single-thread tokio runtime, which caused an abort ("Cannot start a runtime from within a runtime") when pressing tab for file completion (e.g. jq aa<TAB>)
  • Spawn a helper OS thread with its own current_thread runtime to drive async VFS read_dir, avoiding nested block_on
  • Add 28 comprehensive tests covering runtime safety, security boundaries, and integration scenarios

What

The interactive shell runs on a single-threaded tokio runtime. Rustyline calls Completer::complete() synchronously during tab completion. The old code called handle.block_on(self.fs.read_dir(&dir)) from that synchronous callback — nesting block_on inside the already-running runtime, which panics with an abort.

Why

Users hitting tab after any command argument (e.g. jq aa<TAB>) got an immediate abort with no recovery. This made the interactive shell unusable for file completion.

How

Replace handle.block_on() with std::thread::spawn + a fresh current_thread runtime on the spawned thread. The thread overhead is negligible for interactive tab completion. The codebase already had a comment warning about this exact pattern for the Validator impl (line 365-367) but the same mistake existed in the Completer.

Test coverage (28 new tests)

complete_path unit tests (10): basic match, directory trailing slash, no match, nonexistent dir, nested paths, absolute paths, hidden files, sorted results, mixed files/dirs, empty partial

Runtime safety (4): current_thread runtime, multi_thread runtime, 8-thread concurrent completion, 50-iteration stress test

Security tests (8): path traversal stays in VFS (TM-ESC), no host filesystem leak (TM-ESC), no /proc leak (TM-INF), shell metacharacters in filenames (TM-INJ), unicode filenames (TM-UNI), deeply nested paths (TM-DOS), very long filenames (TM-DOS), large directory with 200 entries (TM-DOS), symlink safety

Integration tests (6): cd changes completion scope, mkdir+complete, variable/alias visibility in state, rm removes from completion, script-created batch files visible

chaliy added 2 commits April 11, 2026 18:03
complete_path() called handle.block_on() from within the single-thread
tokio runtime driving the REPL, causing "Cannot start a runtime from
within a runtime" panic on tab press. Spawn a helper thread with its
own runtime to drive async VFS read_dir instead.
Add 28 new tests covering:
- complete_path unit tests: basic match, dirs with trailing slash, no match,
  nonexistent dirs, nested paths, absolute paths, hidden files, multiple
  matches sorting, mixed files/dirs
- Runtime safety: current_thread and multi_thread runtimes, concurrent
  completion from 8 threads, 50-iteration stress test
- Security (TM-ESC/TM-INJ/TM-UNI/TM-DOS): path traversal stays in VFS,
  no host filesystem or /proc leak, shell metacharacters in filenames,
  unicode filenames, deeply nested paths, very long filenames, large
  directory (200 entries), symlink safety, empty partial input
- Integration: cd changes completion scope, mkdir+complete, variable and
  alias visibility in state, rm removes from completion, script-created
  files appear in completion
@chaliy chaliy merged commit 1833ca8 into main Apr 11, 2026
11 checks passed
@chaliy chaliy deleted the claude/fix-jq-runtime-error-KuR3Y branch April 11, 2026 19:37
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.

1 participant