Repository navigation
Conversation
Node's fs.watch listener can be invoked with an undefined filename, not only null. The guard fell through to filename.toString() on undefined and threw a TypeError from the watch callback, surfacing as an unhandled error between tests. Treat a missing filename like null and reconcile the directory, and widen the parameter type so the possibility is visible.
Contributor
Author
|
Swept the class rather than just the instance — there are two
(_event, filename) => {
const isOurs =
filename === name ||
(filename?.startsWith(`${name}.`) && filename.endsWith('.tmp'))
if (filename != null && !isOurs) returnOptional chaining plus So the difference between the two sites is only that one used |
This was referenced Sep 22, 2026
Contributor
Author
|
No longer applies: custody-manifest-watcher.ts was deleted on main (c2f3428). Closing. |
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.
filenameMatchesin the custody manifest watcher guardsfilename === null, but Node'sfs.watchlistener can also be invoked withundefined. When it is, the guard falls through and.toString()throws.The declared parameter type is
string | Buffer | null, so TypeScript never flags the case — the value simply isn't supposed to exist, and at runtime it does.Why it is worth fixing rather than tolerating
This throws inside an
fs.watchcallback, not on a request path, so there is no caller to catch it. In CI it surfaces as1932 pass, 0 fail, 1 error— a red gate with no failing test to point at, which is a genuinely confusing signal to land on someone's PR. In production the same event kills the watcher callback, and the manifest watcher is one half of the pair that keeps custody bindings reconciled (the low-frequency metadata poll is the other). Losing it degrades silently: reconciliation just gets slower, with nothing to say why.undefinedhere carries the same meaningnullalready does — Node could not attribute the change to a specific entry — so the fix routes it to the existing behaviour: reconcile the whole directory.Widening the type matters as much as the guard: it makes the case visible to the next reader instead of leaving a runtime possibility the signature denies.
Verification
The test drives the production callback through the module's existing
watchImplseam rather than calling the helper directly — a helper-level test would keep passing if the caller stopped using it.Red-first, against unfixed code — the real
TypeError, not a tidy assertion failure, confirming the test reaches the production path:Two mutations, both re-run independently of the implementation:
TypeError: undefined is not an objectundefinedmean no match instead of reconcileExpected: > 1 / Received: 1The second is the one that matters: it proves the test asserts the reconcile actually happens, not merely that nothing threw. A fix that swallowed the event silently — which would have looked fine and quietly disabled the watcher — does not pass.
Gates: core 295/0 · opencode 1927/0 · typecheck clean. Clean
mainmeasures 1926 (1924 pass + 2 known intermittents, #220); the +1 is this test.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Fixes the custody manifest watcher crashing when Node invokes the
fs.watchcallback with an undefined filename, which previously threw aTypeErrorand silently degraded reconciliation.nulland reconciles the whole directory instead of throwing.undefinedso the runtime case is visible in the signature.Written for commit 58422fe. Summary will update on new commits.
The PR appears safe to merge with no actionable correctness, security, or repository-rule issues identified.
Summary
This PR safely handles
undefinedfilenames fromfs.watchas directory-level changes, preventing an exception and preserving custody-manifest reconciliation.nullandundefinedas unattributed directory changes.Reviews (1) · Last reviewed commit: "fix(opencode): handle undefined filename..."