A few places rely on (binding [*out* …] …) to redirect output, but the rebinding is currently a no-op, so output lands on the wrong stream:
- Error reports go to stdout, not stderr.
die (cli.lg:6, imgstore.lg:17, container.lg:26) does (binding [*out* *err*] (println …)), but println ignores the *out* rebinding and writes to stdout.
- Container log streaming goes to lgcr's own stdout.
stream-file (container.lg:1060) does (binding [*out* sink] (print chunk)), and it's called with *out*/*err* sinks for stdout.log/stderr.log at container.lg:1344-1345. print ignores the sink binding the same way.
Reproduce on current let-go (no lgcr needed):
$ lg -e '(binding [*out* *err*] (println "x"))' # "x" -> stdout, stderr empty
$ lg -e '(let [f (open "/tmp/s" :write)] (binding [*out* f] (print "y")) (close! f))'
$ cat /tmp/s # empty — "y" went to stdout, not the file
Root cause is upstream: let-go's top-level print fns (print/pr/prn/println) write straight to os.Stdout and don't consult *out*, so (binding [*out* x] (println …)) has no effect. The lgcr code is written correctly per Clojure semantics — the runtime just doesn't honor it yet. Tracked in nooga/let-go#79, which has a proposed fix and a working implementation.
No lgcr code change is needed: once the let-go fix lands and the pin bumps to a release that includes it, die and stream-file start behaving as written. Add a regression test at that point so a later let-go change can't silently re-break error routing.
Filing mainly as a tracking link from the affected project; will close on the pin bump.
A few places rely on
(binding [*out* …] …)to redirect output, but the rebinding is currently a no-op, so output lands on the wrong stream:die(cli.lg:6, imgstore.lg:17, container.lg:26) does(binding [*out* *err*] (println …)), butprintlnignores the*out*rebinding and writes to stdout.stream-file(container.lg:1060) does(binding [*out* sink] (print chunk)), and it's called with*out*/*err*sinks forstdout.log/stderr.logat container.lg:1344-1345.printignores the sink binding the same way.Reproduce on current let-go (no lgcr needed):
Root cause is upstream: let-go's top-level print fns (
print/pr/prn/println) write straight toos.Stdoutand don't consult*out*, so(binding [*out* x] (println …))has no effect. The lgcr code is written correctly per Clojure semantics — the runtime just doesn't honor it yet. Tracked in nooga/let-go#79, which has a proposed fix and a working implementation.No lgcr code change is needed: once the let-go fix lands and the pin bumps to a release that includes it,
dieandstream-filestart behaving as written. Add a regression test at that point so a later let-go change can't silently re-break error routing.Filing mainly as a tracking link from the affected project; will close on the pin bump.