Description
When a user-defined function is invoked as part of a pipeline, the stdin from the pipe is not forwarded to the function body. The function executes with no stdin, so commands like tr, cat, read inside the function receive nothing and produce no output.
Reproduction
to_upper() { tr '[:lower:]' '[:upper:]'; }
echo "hello world" | to_upper
# Expected: HELLO WORLD
# Actual: (empty)
Also fails with source:
# /lib/utils.sh
to_upper() { tr '[:lower:]' '[:upper:]'; }
source /lib/utils.sh
echo "hello world" | to_upper
# Expected: HELLO WORLD
# Actual: (empty)
Root Cause
In crates/bashkit/src/interpreter/mod.rs around line 2756-2778, when execute_dispatched_command handles a user-defined function, the stdin parameter is available but never set on self.pipeline_stdin before calling execute_command(&func_def.body):
if let Some(func_def) = self.functions.get(name).cloned() {
// ...
let mut result = self.execute_command(&func_def.body).await?; // stdin NOT passed
// ...
}
Compare to how compound commands in pipelines correctly handle this at lines 2269-2271:
let prev_pipeline_stdin = self.pipeline_stdin.take();
self.pipeline_stdin = stdin_data.take();
// ... execute ...
self.pipeline_stdin = prev_pipeline_stdin;
Suggested Fix
Set self.pipeline_stdin = stdin; before executing the function body, then restore it after. Same pattern used for compound commands and subshells (e.g., line 3412-3419).
Impact
High — All 4 eval models (Opus, Sonnet, Haiku, GPT) hit this bug. Breaks the script_function_lib eval task entirely. Any function that reads stdin via pipe will silently produce no output.
Found In
Eval run 2026-02-25, task script_function_lib — failed across all models.
Description
When a user-defined function is invoked as part of a pipeline, the stdin from the pipe is not forwarded to the function body. The function executes with no stdin, so commands like
tr,cat,readinside the function receive nothing and produce no output.Reproduction
Also fails with
source:Root Cause
In
crates/bashkit/src/interpreter/mod.rsaround line 2756-2778, whenexecute_dispatched_commandhandles a user-defined function, thestdinparameter is available but never set onself.pipeline_stdinbefore callingexecute_command(&func_def.body):Compare to how compound commands in pipelines correctly handle this at lines 2269-2271:
Suggested Fix
Set
self.pipeline_stdin = stdin;before executing the function body, then restore it after. Same pattern used for compound commands and subshells (e.g., line 3412-3419).Impact
High — All 4 eval models (Opus, Sonnet, Haiku, GPT) hit this bug. Breaks the
script_function_libeval task entirely. Any function that reads stdin via pipe will silently produce no output.Found In
Eval run 2026-02-25, task
script_function_lib— failed across all models.