terminal-bash: persistent shell stalls for the full 300 s timeout on CJK input (C-locale readline reads UTF-8 bytes as Meta bindings) #3522
Replies: 1 comment
|
Thank you for the unusually strong A/B reproduction. It changes the diagnosis materially: a completion listing, mangled command, or PS2 prompt supports a C-locale readline Meta-binding trap, while the earlier visible character-replacement report must remain a separate PTY transport branch. We corrected the community runbook against rc.8 and preserved both mechanisms instead of collapsing them into a generic Unicode timeout. It now includes the exact https://sandbaseai.github.io/deepseek-harness-handbook/macos-bash-nonascii.html The source-backed canonical version is here: The report remains the primary evidence and is linked directly. Results from Linux or a current Bash with an empty locale would help narrow the platform boundary further. |
Uh oh!
There was an error while loading. Please reload this page.
The persistent
bashtool occasionally hangs for exactly the configured timeout (300 s with the shippedminimalpreset) and then fails withYour command timed out after 300 seconds … The persistent bash shell was reset. The model and the shell are both healthy — the stall happens between them.dsh-terminal-bashspawns/bin/bash --noprofile --norc -iwith an environment built from scratch (childEnvironment()) that carries noLANG/LC_*. On macOS/bin/bashis 3.2.57, so the interactive shell enables readline in the C locale, and readline interprets high-bit input bytes as Meta (ESC-prefixed) key bindings. Specific CJK byte sequences in a command then trigger digit-argument/completion machinery, and bash ends up either waiting onDisplay all 127 possibilities? (y or n)or sitting at a PS2 continuation prompt with a mangled line. The prompt marker never returns, and the tool call burns the whole timeout before the shell is killed and reset.Environment
@deepseek-ai/dsh0.1.0-rc.7 (global npm install),dsh web/bin/bash→ GNU bash 3.2.57(1)-releaseminimalpreset (persistent bash tool)What it looks like in real sessions
Measured across 12 sessions / 744
bashtool calls in~/.dsh/sessions:Your command timed out after 300 seconds … The persistent bash shell was reset(the 300 s istimeoutMs: 300000on the preset'sterminal-bashrow)Root cause
packages/terminal/terminal-bash(publishedlib/index.jsin rc.7),childEnvironment():No
LANG/LC_*is set, so the PTY bash runs in the C locale. Combined with the default argv:the interactive bash turns readline on, and in the C locale readline maps high-bit bytes to Meta bindings. The stall is input-dependent:
echo "=== 相关进程 ==="reliably wedges the shell.Notes on scope:
bash -c '<cmd>'is non-interactive (no readline), so the same command always works there. The same command in Terminal.app also works, because a normal terminal inherits a UTF-8LANG.Reproduction
Self-contained script using the same
node-ptythe harness ships, dsh's exact argv + env contract, one CJK command (adjust the install path, ornpm i node-ptyin a scratch dir):Results on my machine (A = as shipped; B/C = the two one-line fixes):
(A's tail shows this run landing on a completion listing plus a mangled line left at the PS2
>continuation prompt. Other runs of the same command land onDisplay all 127 possibilities? (y or n)instead. Either way the prompt marker never returns and the shell sits until the tool timeout kills it.)Suggested fixes (both validated: 5/5 CJK commands, ~25 ms each)
childEnvironment()— e.g.LANG: process.env.LANG ?? "en_US.UTF-8". Explicit defaulting is the robust form: on macOS a GUI-launched process typically has noLANGto inherit in the first place.--noeditingin the defaultshellArgs. The persistent shell is driven programmatically, so readline line editing is never used, and disabling it removes the entire class of Meta-binding stalls. The OSC 133;D +PS1prompt-detection contract is unaffected (verified with the exact env above).envfield to the plugin's Config schema, so users can inject locale variables without ashellPathwrapper script.Workaround for users today
Patch the
terminal-bashrow in the agent preset composition (e.g.config/agent-presets/minimal/agent.cordis.yml, or a user preset under~/.dsh/.agent-presets/). Preset composition files are picked up by newly created sessions without a restart:Note: a
terminal-bash:section in~/.dsh/settings.yamlhas no effect — this plugin registers no settings namespace, so its config can only come from the loader entry (the preset composition row).All reactions