What is the current bug behavior?
--variables-file fails when the file is a FIFO (named pipe). Hurl does a single read() on the file descriptor and gets whatever bytes are in the pipe buffer at that instant — often a partial chunk — instead of looping until EOF. The variables are left empty, truncated, or parsed from a fragment of a comment line, causing Undefined variable / Missing value for variable / Assert status code errors.
Steps to reproduce
- Create a FIFO and a test hurl file:
mkdir /tmp/hurl-fifo-repro && cd /tmp/hurl-fifo-repro
mkfifo vars.env
printf 'GET https://httpbin.org/get\nX-Api-Key: {{api_key}}\nHTTP 200\n' > test.hurl
- Control — regular file (works):
printf 'api_key=fakevalue123\n' > vars-regular.env
hurl --variables-file vars-regular.env test.hurl
# exit 0, HTTP 200
- FIFO — fails 5/5:
for i in 1 2 3 4 5; do
(printf 'api_key=fakevalue123\n' > vars.env) &
hurl --variables-file vars.env test.hurl 2>&1 | head -1
echo "attempt $i exit: ${PIPESTATUS[0]}"
done
# error: Assert status code (or "Undefined variable" / "Missing value for variable"
# depending on which partial chunk arrives)
# exit 4 (or 3), 5/5 failures
The error varies depending on which bytes arrive in the partial read:
- Empty chunk →
Undefined variable (exit 3)
- Comment fragment parsed as
name=value → Missing value for variable <fragment> (exit 1)
- Truncated
key=value → empty/partial value sent to the request → Assert status code (exit 4)
What is the expected correct behavior?
--variables-file should loop on read() until EOF (0 bytes returned), accumulating the full file contents before parsing — the same way cat, grep, and other standard tools handle FIFOs. A FIFO is a valid file type per POSIX, and open() + read() work on it; the reader just needs to drain the pipe completely.
Execution context
- OS: macOS 15 (Darwin 25.5.0)
- Hurl Version: 8.0.1
- Found via 1Password Environments (beta), which mounts
.env files as FIFOs fed on demand by the 1Password desktop app instead of writing plaintext secrets to disk. --variables-file fails ~100% of the time on these mounts — the real-world trigger for this report.
Possible fixes
The variables-file reader likely uses a single read() or read_to_end() equivalent that doesn't loop on pipes. Replacing it with a loop-until-EOF read (e.g., std::io::Read::read_to_end / read_to_string which loop internally, or an explicit loop) should fix it. Rust's std::fs::File → std::io::Read::read_to_string handles this correctly because it loops until EOF.
What is the current bug behavior?
--variables-filefails when the file is a FIFO (named pipe). Hurl does a singleread()on the file descriptor and gets whatever bytes are in the pipe buffer at that instant — often a partial chunk — instead of looping until EOF. The variables are left empty, truncated, or parsed from a fragment of a comment line, causingUndefined variable/Missing value for variable/Assert status codeerrors.Steps to reproduce
The error varies depending on which bytes arrive in the partial read:
Undefined variable(exit 3)name=value→Missing value for variable <fragment>(exit 1)key=value→ empty/partial value sent to the request →Assert status code(exit 4)What is the expected correct behavior?
--variables-fileshould loop onread()until EOF (0 bytes returned), accumulating the full file contents before parsing — the same waycat,grep, and other standard tools handle FIFOs. A FIFO is a valid file type per POSIX, andopen()+read()work on it; the reader just needs to drain the pipe completely.Execution context
.envfiles as FIFOs fed on demand by the 1Password desktop app instead of writing plaintext secrets to disk.--variables-filefails ~100% of the time on these mounts — the real-world trigger for this report.Possible fixes
The variables-file reader likely uses a single
read()orread_to_end()equivalent that doesn't loop on pipes. Replacing it with a loop-until-EOF read (e.g.,std::io::Read::read_to_end/read_to_stringwhich loop internally, or an explicit loop) should fix it. Rust'sstd::fs::File→std::io::Read::read_to_stringhandles this correctly because it loops until EOF.