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
Since the v0.4.14 boundary guard landed (#3021, shipped in #3052), org-scoped queries reaching the server with organizationId: "" are rejected as structured ORG_ID_REQUIRED. The client is still sending them:
Uncaught RLSError: Organization id is required.
GlitchTip TALE-PROJECT-11R — born 2026-08-25T06:11Z, hours after v0.4.14 deployed, exactly as the fix(platform): classify dead-org errors and recover stale clients #3052 review predicted for the residual caller-side gap. 32 events by 2026-08-27T02:19Z and accelerating (10 by 8/25 12:42Z → 26 by 8/26 11:48Z → 32 now), from authenticated demo users in normal use — not stale tabs.
All 32 events carry func: governance/queries:getPolicy; no other org-scoped function has ever fired with an empty id.
Pre-guard predecessor: TALE-PROJECT-OU — Not a member of organization <empty>, 92 events 2026-07-07 → 2026-08-25, quiet since the guard went live. Its sampled events were the same getPolicy path (40/42).
Components mount org-scoped subscriptions while their parent record is still resolving, substituting '' for the org id. The one chain matching every live event:
task-modal.tsx#L1026-L1029 — useConvexFileUpload({ organizationId: task?.organizationId ?? '', … }) mounts while useTask(taskId) is still resolving, so task is undefined
The same file already has the house pattern next door: usePasswordPolicy (#L100-L108) passes 'skip' until the org id is truthy — as do useAccessibleModels, useLegalHolds, useOrgMembersForPicker.
Where else (same class)
Unguarded siblings in the same file — will fire for any falsy caller: usePiiConfig (L45), useDsarPolicyForUi (L62), useMyFeatureFlags (L68), useMyBudgetStatus (L74).
Known ?? '' feeders (zero server events to date, but the same race): task-modal.tsx L984 useActorDirectory, L996 useTaskStatusChoreography, L1000 useTaskSubjectContract; kanban-board.tsx L55 and use-task-board-dnd.ts L92 (tasks[0]?.organizationId ?? ''); message-toolbar.tsx L89 (useFeedbackActions); dictation-button.tsx L82; members-settings.tsx L68.
Suggested
'skip'-on-falsy guard in useGovernancePolicy and the four unguarded siblings — the smallest change that silences the live stream, and it covers every current and future caller of those hooks.
Sweep the ?? '' call sites so org-scoped queries pass 'skip' (or don't mount) until a real id exists.
Close the class: dev-assert (or auto-skip) in useConvexQuery when an organizationId arg is '', or type org ids so ?? '' no longer typechecks into query args.
Acceptance
Opening/closing the task modal (including the E2E project specs) produces no new ORG_ID_REQUIRED events.
TALE-PROJECT-11R stays flat after the next demo deploy; no '' org id leaves the client.
Tracking
Board task: TAL-9 "Org-scoped queries fire with empty organizationId (?? '' races) — sweep call sites so ORG_ID_REQUIRED goes quiet"
Problem
Since the v0.4.14 boundary guard landed (#3021, shipped in #3052), org-scoped queries reaching the server with
organizationId: ""are rejected as structuredORG_ID_REQUIRED. The client is still sending them:func: governance/queries:getPolicy; no other org-scoped function has ever fired with an empty id.Not a member of organization <empty>, 92 events 2026-07-07 → 2026-08-25, quiet since the guard went live. Its sampled events were the samegetPolicypath (40/42).Root cause (verified at 0453e65)
Components mount org-scoped subscriptions while their parent record is still resolving, substituting
''for the org id. The one chain matching every live event:task-modal.tsx#L1026-L1029—useConvexFileUpload({ organizationId: task?.organizationId ?? '', … })mounts whileuseTask(taskId)is still resolving, sotaskisundefineduse-convex-file-upload.ts#L104—useUploadPolicy(config.organizationId)unconditionallygovernance/hooks/queries.ts#L253-L254—useUploadPolicy→useGovernancePolicy(organizationId, 'upload_policy')governance/hooks/queries.ts#L52-L59—useGovernancePolicysubscribes with no'skip'guard, so the''goes over the wire.The same file already has the house pattern next door:
usePasswordPolicy(#L100-L108) passes'skip'until the org id is truthy — as douseAccessibleModels,useLegalHolds,useOrgMembersForPicker.Where else (same class)
Unguarded siblings in the same file — will fire for any falsy caller:
usePiiConfig(L45),useDsarPolicyForUi(L62),useMyFeatureFlags(L68),useMyBudgetStatus(L74).Known
?? ''feeders (zero server events to date, but the same race):task-modal.tsxL984useActorDirectory, L996useTaskStatusChoreography, L1000useTaskSubjectContract;kanban-board.tsxL55 anduse-task-board-dnd.tsL92 (tasks[0]?.organizationId ?? '');message-toolbar.tsxL89 (useFeedbackActions);dictation-button.tsxL82;members-settings.tsxL68.Suggested
'skip'-on-falsy guard inuseGovernancePolicyand the four unguarded siblings — the smallest change that silences the live stream, and it covers every current and future caller of those hooks.?? ''call sites so org-scoped queries pass'skip'(or don't mount) until a real id exists.useConvexQuerywhen anorganizationIdarg is'', or type org ids so?? ''no longer typechecks into query args.Acceptance
ORG_ID_REQUIREDevents.''org id leaves the client.Tracking
?? ''races) — sweep call sites so ORG_ID_REQUIRED goes quiet"