Found while censusing predicate-fault catch sites for #6038. Filed unassigned; out of that card's scope, which the 2026-08-25 ruling scopes to a visibleWhen / node-gate visibility predicate.
The site
packages/react/src/SchemaRenderer.tsx, immediately below the visibility chain:
constisDisabled=(()=>{if(hasDeclaredPredicate(newSchema.disabled)){returnevaluator.evaluateCondition(newSchema.disabled);}if(hasDeclaredPredicate(newSchema.disabledOn)){returnevaluator.evaluateCondition(newSchema.disabledOn);}returnfalse;})();The visibility chain three lines above routes every leg through evaluateVisibilityPredicate, which reports a fault (in development since #5454, and in production since #6038). This one calls evaluateCondition bare — so a faulting disabled predicate has never been reported, in either build, in any dialect that does not report on its own.
Why the polarity makes it worth its own card
evaluateCondition's answer for an unevaluable predicate is true. On the negated visibility legs that means SHOWN; on disabled it means GREYED OUT. This file already carries the analysis for the neighbouring case (#3862/#3955): an empty disabled predicate disabling the node was a real defect, and the comment there records the asymmetry — "a greyed-out control is still on screen, a node that never rendered is indistinguishable from metadata that meant it."
So the failure mode here is a control the user can see and cannot use, with no console line naming the predicate. That is a support ticket ("the Save button is greyed out and I don't know why") with nothing to grep for.
Cost
The expensive part of this question was settled by #6038: EvaluationOptions.onFault reports the fault the evaluator has already caught, at the same number of engine calls — no throwOnError double-evaluation — and the reporter, message and rate limit already exist. The remaining work is the wiring plus a decision on the message text, since reportUnresolvableVisibilityPredicate's copy is written about a visibility gate ("the gate did NOT bite") and is wrong for this polarity: here the safe default is the one that bites.
Related: #6038 (the ruling, the seam, the reporter), #3862 and #3955 (the disabled/hidden declared-predicate rulings this polarity analysis comes from).
Generated by Claude Code
Found while censusing predicate-fault catch sites for #6038. Filed unassigned; out of that card's scope, which the 2026-08-25 ruling scopes to a
visibleWhen/ node-gate visibility predicate.The site
packages/react/src/SchemaRenderer.tsx, immediately below the visibility chain:The visibility chain three lines above routes every leg through
evaluateVisibilityPredicate, which reports a fault (in development since #5454, and in production since #6038). This one callsevaluateConditionbare — so a faultingdisabledpredicate has never been reported, in either build, in any dialect that does not report on its own.Why the polarity makes it worth its own card
evaluateCondition's answer for an unevaluable predicate istrue. On the negated visibility legs that means SHOWN; ondisabledit means GREYED OUT. This file already carries the analysis for the neighbouring case (#3862/#3955): an emptydisabledpredicate disabling the node was a real defect, and the comment there records the asymmetry — "a greyed-out control is still on screen, a node that never rendered is indistinguishable from metadata that meant it."So the failure mode here is a control the user can see and cannot use, with no console line naming the predicate. That is a support ticket ("the Save button is greyed out and I don't know why") with nothing to grep for.
Cost
The expensive part of this question was settled by #6038:
EvaluationOptions.onFaultreports the fault the evaluator has already caught, at the same number of engine calls — nothrowOnErrordouble-evaluation — and the reporter, message and rate limit already exist. The remaining work is the wiring plus a decision on the message text, sincereportUnresolvableVisibilityPredicate's copy is written about a visibility gate ("the gate did NOT bite") and is wrong for this polarity: here the safe default is the one that bites.Related: #6038 (the ruling, the seam, the reporter), #3862 and #3955 (the
disabled/hiddendeclared-predicate rulings this polarity analysis comes from).Generated by Claude Code