fix(sync): the apply failure path silenced the shell's stderr, starting with #911's diagnostic - #974
Open
fujibee wants to merge 1 commit into
Open
fix(sync): the apply failure path silenced the shell's stderr, starting with #911's diagnostic#974fujibee wants to merge 1 commit into
fujibee wants to merge 1 commit into
Conversation
…derr `_sqlite_sync_apply_fail` closed fd 3 as `exec 3<&- 2>/dev/null`. With no command word, bash does not scope that redirection to anything — it applies it to the shell, permanently. Every `>&2` after the first apply failure went to /dev/null. It sits on the failure path, so what it silences is the output a failing apply is about to produce. The first thing lost is the message #911 added this morning, naming which check returned 13 — the diagnostic that made today's work possible, disabled a few hundred lines away in the same file. `{ exec 3<&-; } 2>/dev/null` scopes it to the block. Two tests, because either alone passes while the other's failure ships: one lifts the driver's own function body out of the file by line range and calls it (a copy of the shape would keep passing while the driver regressed), one greps the file for a bare `exec` carrying a redirection. Both go red on the old form. Reported by @joelmitz, who also identified #911 as the first casualty.
fujibee
force-pushed
the
fix/apply-fail-silences-stderr
branch
from
August 25, 2026 16:07
e056478 to
33100cd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reported by @joelmitz on 2026-08-22, reproduced here.
execwith no command word does not run anything — it applies its redirections to the current shell, and they stay. The intent is "close fd 3, and say nothing if closing an already-closed fd complains". The effect is that the shell's stderr is pointed at /dev/null for the rest of the process.What it costs
_sqlite_sync_apply_failis the failure path. It runs when an apply has already gone wrong, which is exactly when the messages that follow it matter. Everything written to stderr after the first failure — in that process — is discarded.The first thing lost is the message #911 added this morning, naming which check returned 13. That diagnostic is what made the rest of today's work possible: the incident in #910 presented as
exit 13with nothing else, and #911 existed so that would not happen again. It was disabled a few hundred lines away in the same file, on the path where it is needed.@joelmitz named that consequence in the report, which is the part that makes this worth fixing today rather than filing.
The fix
The redirection now belongs to the block.
Tests
Two, because either one alone passes while the other's regression ships:
_sqlite_sync_apply_fail's body out of the driver by line range and calls it, then writes to stderr and asserts the write is visible. The function is nested insidestorage_sync_apply_pulland cannot be sourced; writing a copy of the shape into the test would keep passing while the driver regressed, which is the failure this test exists to catch.execcarrying a redirection. Catches the same mistake written a different way, anywhere in the file.Both were confirmed to go red against the old line and green against the new one.
The other two
execsites in the tree are fine:codex-bridge-launcher.sh:13carries no redirection, andcodex-monitor.sh:128is inside a subshell, which scopes it.