Skip to content

rtk err re-splits child command argv on whitespace — quoted arguments corrupted, exit codes silently wrong #2389

Closed

Description

@disi-omni

Version: rtk 0.42.3 (macOS arm64, Homebrew)

rtk err does not preserve the argv vector of its child command. The trailing [COMMAND]... args are flattened and re-split on whitespace, so any single quoted argument containing a space is split into multiple arguments. rtk proxy preserves argv correctly, which isolates the defect to the err path.

Minimal repro (argv inspection):

cat > /tmp/argspy <<'EOF'
#!/bin/sh
printf 'argc=%s\n' "$#"
for a in "$@"; do printf 'arg=[%s]\n' "$a"; done
EOF
chmod +x /tmp/argspy

$ rtk err /tmp/argspy 'a b' c
argc=3
arg=[a]
arg=[b]          # ← 'a b' was split
arg=[c]

$ rtk proxy /tmp/argspy 'a b' c
argc=2
arg=[a b]        # ← correct
arg=[c]

Observable consequence — exit code silently wrong:

$ rtk err sh -c 'exit 7'; echo "exit:$?"
[ok] Command completed successfully (no errors)
exit:0           # ← expected 7

$ rtk err -- sh -c 'exit 7'; echo "exit:$?"
[ok] Command completed successfully (no errors)
exit:0           # ← `--` does not help

$ printf '#!/bin/sh\nexit 7\n' > /tmp/exit7.sh; chmod +x /tmp/exit7.sh
$ rtk err /tmp/exit7.sh; echo "exit:$?"
[FAIL] Command failed (exit code: 7)
exit:7           # ← a flagless command works correctly

Mechanism: rtk err sh -c 'exit 7' reaches sh as sh -c exit 7 (the quoted exit 7 re-split into exit + 7). Per POSIX, sh -c exit 7 runs the one-word script exit with $0=7, which exits 0 — so the real failure is masked. Confirmed independently: plain sh -c exit 7 → 0, sh -c 'exit 7' → 7.

Impact: any rtk err <cmd> whose child takes a quoted argument containing whitespace — sh -c '…', bash -c '…', make -C 'dir with space', node -e 'a; b' — runs a corrupted command. Because err reports status from the (wrong) child, hard failures can be reported as success.

Expected: rtk err should pass the child argv through verbatim, exactly as rtk proxy does.

Activity

  1. pszymkowiak commented on Jun 11, 2026

    @pszymkowiak
    Collaborator

    wshm · Automated triage by AI

    🔍 Automated Triage

    🐛 Category bug
    🟠 Priority high
    🎯 Confidence 96%

    Summary

    rtk err flattens and re-splits argv on whitespace, corrupting quoted arguments and silently masking non-zero exit codes; fix by passing argv verbatim as rtk proxy already does

    This looks like a simple fix that could be auto-resolved. Repo maintainers can use /wshm fix to attempt it.

    📁 Relevant files
    • src/commands/err.rs
    • src/commands/proxy.rs

    Triaged automatically by wshm · This is an automated analysis, not a human review.

  2. KennyAtCodin commented on Sep 16, 2026

    @KennyAtCodin

    Reproduces on rtk 0.48.0 (Windows 11, Git Bash):

    rtk err node -e "console.log('noise'); console.error('error: boom'); process.exit(3)"
    echo $?

    This prints [ok] Command completed successfully (no errors) and exits 0. The inline script loses its quoting, Node fails on the syntax, and the failure is reported as success. Running the same code from a script file works correctly: rtk err node fail.js prints only the error line and exits 3.

    This false green is the most dangerous part for agent use, because an agent trusts the [ok] line and the exit code.

  3. MincongZhou commented on Sep 23, 2026

    @MincongZhou

    Opened #4206 for this. A multi-word argv now reaches the child as a vector — the same route rtk proxy already takes — with resolved_command + ChildArgExt reused rather than a second quoting path. A lone argument stays a shell string, so rtk err '<cmd> && <cmd>' keeps composing. Repro and before/after are in the PR body.

  4. KuSh commented on Sep 26, 2026

    @KuSh
    Collaborator

    This is fixed on develop by #4125, which makes rtk err run the child with its argument vector intact instead of re-splitting it through a shell: rtk err sh -c 'exit 7' now reports exit code 7 and a quoted 'a b' argument reaches the child as one argument. The change is not in a stable release yet, so labeling it resolved-pending-close; it will be closed once a release containing the fix ships. If it still happens on that release, please comment here.

  5. KuSh commented on Oct 3, 2026

    @KuSh
    Collaborator

    Fixed by #4125, shipped in v0.51.0: rtk err now passes the child its argument vector unchanged. rtk err sh -c 'exit 7' reports exit code 7 and a quoted 'a b' argument reaches the child as one argument. If you still see a split argument or a false success on v0.51.0 or later, please comment and we will reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions