You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Every record-detail page load logs record is not defined for a bare-string predicate that is in fact working — a permanently-misleading diagnostic on the happy path #5776
Provenance: rebuilt from objectstack-ai/objectstack#11247 (filed there by the #9167 measurement round because the measuring dev was fenced out of this repo; transferred by the triage seat 2026-08-23 under multi-repo rule 1 — strip objectstack from the description and it still stands; the logging evaluator and renderer live here). Source card closed as moved.
What was observed
Measured in a real console at objectui pin 190fbd01d during the objectstack#9167 measurement round (2026-08-23, full evidence on that card).
On every record-detail page load carrying a bare-string page-block predicate — including the ordinary, correct ones — the console logs an evaluation failure for the loading frame:
Failed to evaluate expression: ${record.status == 'in_review'}
Error: ... record is not defined
Observed on A1 (banner correctly shown), A2 (banner correctly hidden), and B1/B2 alike. It is emitted in every polarity, on pages where the predicate demonstrably works.
Why it is worth a card
It is not a symptom of anything being wrong — and that is exactly the problem. An author debugging a page-block predicate sees record is not defined on a page where the predicate functions correctly. The diagnostic is permanently misleading on the happy path: it invites a fix for a non-defect, and it trains readers to ignore a message that would matter if it ever fired for a real reason. The platform's strategy on predicate faults is to make them loud and accurate (the CEL face names its missing key: [runtime] No such key: status); a warning that cries wolf on every load degrades that channel.
Mechanism locus
The loading frame of the legacy evaluator path: the bare-string predicate is evaluated before the record binding exists, the failure is logged, and a later frame evaluates correctly. record-alert.tsx / predicateInput.ts at the pinned SHA are the read entry points (read for explanation in the source round, not as evidence).
Sizing datum (measured, bounds the value)
At the same pin, all 6 authored visibleWhen values served across 34 pages are {dialect:'cel'} envelopes and 0 are bare; the only 2 record:alert blocks in existence carry visible as bare strings. The bare-string path is a small and shrinking surface — the fix is diagnostic hygiene, not a behavior change.
Scope as queued
Make the loading-frame evaluation of a bare-string predicate not emit a spurious error when the failure is "binding not yet present" (defer, suppress-first-frame, or downgrade-with-context — dev measures which is honest); a predicate that fails after its bindings exist must still fail loudly. Pin both halves: happy-path load logs nothing; a genuinely-broken predicate still reports.
Dispatching to a dev this round (R25). ⚠️ Note for the dev, carried into the brief: this card was rebuilt from objectstack#11247 by the triage seat under multi-repo rule 1, so its evidence was gathered at objectui pin 190fbd01d — re-anchor every citation on today's origin/main, which has moved a long way since (among other things @objectstack/* refreshed to 17.2.0 this morning, #5668/PR #5790).
{
"issue": 5776,
"status": "done",
"branch": "claude/issue-5776-record-not-defined-loading-frame",
"pr": "https://github.com/objectstack-ai/objectui/pull/5797",
"premise_still_valid": true,
"summary": "Re-anchored on today's origin/main (cd6a328fe) and reproduced the exact mechanism: record-alert.tsx's visible predicate is evaluated on every render including the frame before useRecordContext().data loads, where usePredicateRecordContext binds an empty context bag (no `record` key), so a bare/${...} predicate referencing record.* faults with `record is not defined` and logs via console.warn -- on every load, both polarities, even though the banner's own visibility was always correct. Fixed by deriving one `recordLoaded` flag (record != null and non-empty) and reusing it both to gate what useCondition evaluates (undefined predicate short-circuits without touching the evaluator while unloaded) and as the existing hide-while-unloaded early return, so the two conditions can never drift apart.",
"tests": "Reproduced first (red pre-fix) with a new test asserting no evaluation-failure warning during the loading frame -- confirmed it failed with the exact quoted message before any fix. After the fix: packages/plugin-detail/src/renderers/__tests__/record-alert.loadingFrameDiagnostic.test.tsx (2 tests, new) + record-alert.test.tsx + record-alert.rowBinding.test.tsx + record-alert.visibleWhen.evidence.test.tsx = 39/39 passed (`pnpm exec vitest run <paths>`, repo root per this repo's vitest-invocation-guard). Full package: `pnpm exec vitest run packages/plugin-detail/` = 868/868 passed. `pnpm --filter @object-ui/plugin-detail run type-check` clean (tsc --noEmit + tsconfig.test.json). Targeted `eslint --no-inline-config` on both touched files: 0 errors (pre-existing no-explicit-any warnings only, matching file's existing style). Pairing test explicitly proves a genuinely-broken predicate (referencing an unrelated unbound field) against an ALREADY-loaded record still logs `Failed to evaluate expression` -- the diagnostic is scoped down, not deleted. `node scripts/check-changeset-presence.mjs` and `check-changeset-no-major.mjs` both pass with the added patch changeset.",
"open_questions": [],
"out_of_scope_findings": []
}
Activity
claude commentedon Aug 23, 2026
Claim —
domain:uiexecution seat.session_01EuPCi56cnGyykygi3z9w4mclaude/issue-5776-record-not-defined-loading-frameDispatching to a dev this round (R25).⚠️ Note for the dev, carried into the brief: this card was rebuilt from objectstack#11247 by the triage seat under multi-repo rule 1, so its evidence was gathered at objectui pin
190fbd01d— re-anchor every citation on today'sorigin/main, which has moved a long way since (among other things@objectstack/*refreshed to 17.2.0 this morning, #5668/PR #5790).Generated by Claude Code
fix(plugin-detail): stop the loading-frame `record is not defined` no…
os-zhuang commentedon Aug 23, 2026
os-dev-report
{ "issue": 5776, "status": "done", "branch": "claude/issue-5776-record-not-defined-loading-frame", "pr": "https://github.com/objectstack-ai/objectui/pull/5797", "premise_still_valid": true, "summary": "Re-anchored on today's origin/main (cd6a328fe) and reproduced the exact mechanism: record-alert.tsx's visible predicate is evaluated on every render including the frame before useRecordContext().data loads, where usePredicateRecordContext binds an empty context bag (no `record` key), so a bare/${...} predicate referencing record.* faults with `record is not defined` and logs via console.warn -- on every load, both polarities, even though the banner's own visibility was always correct. Fixed by deriving one `recordLoaded` flag (record != null and non-empty) and reusing it both to gate what useCondition evaluates (undefined predicate short-circuits without touching the evaluator while unloaded) and as the existing hide-while-unloaded early return, so the two conditions can never drift apart.", "tests": "Reproduced first (red pre-fix) with a new test asserting no evaluation-failure warning during the loading frame -- confirmed it failed with the exact quoted message before any fix. After the fix: packages/plugin-detail/src/renderers/__tests__/record-alert.loadingFrameDiagnostic.test.tsx (2 tests, new) + record-alert.test.tsx + record-alert.rowBinding.test.tsx + record-alert.visibleWhen.evidence.test.tsx = 39/39 passed (`pnpm exec vitest run <paths>`, repo root per this repo's vitest-invocation-guard). Full package: `pnpm exec vitest run packages/plugin-detail/` = 868/868 passed. `pnpm --filter @object-ui/plugin-detail run type-check` clean (tsc --noEmit + tsconfig.test.json). Targeted `eslint --no-inline-config` on both touched files: 0 errors (pre-existing no-explicit-any warnings only, matching file's existing style). Pairing test explicitly proves a genuinely-broken predicate (referencing an unrelated unbound field) against an ALREADY-loaded record still logs `Failed to evaluate expression` -- the diagnostic is scoped down, not deleted. `node scripts/check-changeset-presence.mjs` and `check-changeset-no-major.mjs` both pass with the added patch changeset.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
fix(plugin-detail): stop the loading-frame `record is not defined` no…