`flm list --json --quiet` prints status line to stdout, breaking JSON consumers
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.9k
- Forks
- 152
- Avg merge
- 4h 14m
- Merged PRs (30d)
- 11
Description
Summary
flm list --json --quiet (and flm version --json, flm validate --json) print a [FLM] Fetching models from: ... status line to stdout before the JSON payload. This breaks downstream JSON parsers that expect stdout to contain only JSON. The --json and --quiet flags should suppress or redirect the status line.
Environment
- FLM version:
v0.9.45(built from source per docs/linux-getting-started.md, installed to/opt/fastflowlmand symlinked into/usr/local/sbin/flm) - OS: Fedora 43, x86_64
- Hardware: AMD Ryzen AI MAX+ 395 (Strix Halo, XDNA2 NPU)
- Install location:
/usr/local/sbin/flm(system PATH install; binary lives at/opt/fastflowlm/bin/flm)
Reproduction
$ flm list --json 2>/dev/null | head -3
[FLM] Fetching models from: /opt/fastflowlm/share/flm/model_list.json
{
"models": [
{
The [FLM] Fetching models from: ... line is written to stdout (not stderr), even with both --json and --quiet flags set.
Attempting to parse the output as JSON fails:
$ flm list --json 2>/dev/null | python3 -c "import json, sys; json.load(sys.stdin)"
Traceback (most recent call last):
File "<string>", line 1, in <module>
...
json.decoder.JSONDecodeError: Expecting value: line 1 column 2 (char 1)
The same flm list --json --quiet output (with stderr already discarded) still includes the status line on stdout. Same applies to flm version --json:
$ flm version --json 2>/dev/null
[FLM] Fetching models from: /opt/fastflowlm/share/flm/model_list.json
{ "version": "0.9.45" }
Expected behaviour
When --json is set, stdout should contain only the JSON document. Status / diagnostic messages like [FLM] Fetching models from: ... should either:
- Be suppressed when
--jsonis set, OR - Be written to stderr (not stdout), so that
2>/dev/nullremoves them cleanly.
Actual behaviour
The status line is written to stdout, interleaved with the JSON payload, making the JSON unparseable without additional filtering.
Impact
This breaks any JSON consumer that calls flm list --json, flm version --json, or flm validate --json. A notable example is Lemonade Server's FastFlowLM model-discovery code path (src/cpp/server/backends/fastflowlm/fastflowlm_models.cpp), which calls flm list --json and tries to parse the output with a strict JSON parser. When parsing fails, no FLM-managed models are exposed through Lemonade's OpenAI-compatible API, even though the models are installed on the NPU and flm list (without --json) reports them correctly. Models appear "not downloaded" and load requests fail.
Workaround
Consumers can wrap flm with a shell script that strips lines starting with [FLM] from stdout for JSON-output commands only:
#!/bin/bash
FLM_BIN=/usr/local/sbin/flm
for arg in "$@"; do
case "$arg" in
list|version|validate)
output=$("$FLM_BIN" "$@" 2>/dev/null)
rc=$?
printf '%s\n' "$output" | grep -v '^\[FLM\]' || true
exit "$rc"
;;
esac
done
exec "$FLM_BIN" "$@"
Note that this wrapper must NOT filter [FLM] lines for other commands (e.g. pull, serve, run) because Lemonade's flm_download() parses [FLM] Downloading X/Y lines on stdout to extract download progress.
Suggested fix
In the list / version / validate commands, when --json is set:
- Send the
[FLM] Fetching models from: ...status line to stderr instead of stdout, OR - Suppress it entirely (along with
--quiet's current quietening of other status messages).
Either approach is backwards-compatible — consumers that wanted the status line would have had to scrape it from mixed stdout, which is fragile anyway.
Thank you — helpful project.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Locate the CLI handlers for list, version, and validate, then search for the [FLM] Fetching models from: status message and inspect how --json and --quiet are handled. Reproduce the commands from the issue and verify that stdout contains only parseable JSON while status output is suppressed or sent to stderr.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100