Condition Builder encoded query not updated before consumer reads it (async race)DescriptionWhen a user selects a value in the Condition Builder and immediately clicks a button or action that reads the encoded query (e.g. Save Filter, Apply Filter, or a custom UIB client script), the consumer receives a **stale or empty encoded query** instead of the one reflecting the just-selected value. This manifests in multiple surfaces: - **WSD Workplace / Schedule View**: selecting a building reference field value then quickly clicking Save Filter saves `building=` (empty) instead of `building=<sys_id>` - **UI Builder pages with Condition Builder component v2**: a client state parameter bound to the `Query updated` event lags behind — clicking a button immediately after adding a condition reads the old client state value Root Cause The Condition Builder encodes its internal decoded query into an encoded string via an **asynchronous HTTP POST** to a GraphQL data broker endpoint (`DB_API_EXEC_REST_URL`). The round-trip takes variable time depending on server speed and network latency. When a user selects a value: 1. The decoded query is updated synchronously (in-memory component state) 2. An async encode request is dispatched to the backend 3. The `NOW_PREDICATE_BUILDER_CTRL#ENCODED_QUERY_UPDATED` event fires **only after the HTTP response returns** If a consumer (Save Filter button, Apply Filter client script, UIB client state binding, custom script) reads the encoded query **before the HTTP response returns**, it receives the last-known encoded query — which may be stale (from the previous state) or empty (from the initial bootstrap encode before any value was selected). There is no synchronization mechanism that blocks consumers until the encode is complete. The `sn-save-filter` component's early-return guard (`if (!encodedQuery) return`) does not protect against stale non-empty values like `building=`. This is **working as expected** per the current architecture — the async backend round-trip is by design. It is not a bug in the Condition Builder encode logic itself. Conditions for Occurrence All of the following increase the likelihood of hitting the race: - **Slow server or high network latency** — widens the timing window; more likely on customer production instances or first login (cold cache) - **Consumer reads encoded query immediately after value selection** — no deliberate pause between selecting a value and clicking Save/Apply/submit - **Bootstrap encode fires with empty/partial state** — when the filter modal or CB component opens with a partially-built condition (field and operator set, value empty), the initial encode returns a partial query; this becomes the stale value the consumer reads if the user selects a value and immediately clicks Platform Fix The underlying issue is tracked in **EPIC1150689**: move the encode/conversion logic from the backend (async HTTP to data broker) to the **front-end**. This eliminates the async round-trip entirely — the encoded query would be computed synchronously in the browser, making it available immediately after a value change. Until EPIC1150689 ships, the async race is inherent to the architecture and cannot be resolved at the instance or configuration level. Steps to Reproduce Open a page with a Condition Builder component that includes a reference field (e.g. Workplace Central → Event Planner → Schedule View → filter icon, or any UIB page with Condition Builder v2) Add a filter condition using a reference field (e.g. "Building is <value>") Select a value from the reference field lookup Immediately click Save Filter, Apply, or any button that reads the encoded query — without pausing after the value selection Observe that the resulting encoded query contains an empty value (e.g. building= instead of building=<sys_id>) Reproduction tip: The race is timing-dependent. It is more reliably reproduced on slower instances, on first login (cold cache), or by clicking Save/Apply within ~500ms of selecting the reference value. On fast local/SNC instances the encode may complete before the click, making it difficult to reproduce consistently.Workaround **For end users:** After selecting all filter values, wait approximately 1–2 seconds before clicking Save Filter or Apply. This allows the async encode HTTP response to complete and update the encoded query before it is read. Alternatively: if the filter saves incorrectly, click Save Filter a second time. By the second click the encode has completed and the correct query is used. **For developers building UIB pages:** Do not read the encoded query synchronously from a client state or button click handler immediately after a value change. Instead, consume the `NOW_PREDICATE_BUILDER_CTRL#ENCODED_QUERY_UPDATED` event directly as the trigger for downstream actions — this event fires only after the encode completes and carries the correct encoded query in its payload (`event.payload.value`). **Example pattern (correct):** ``` Trigger: "Query updated" event from Condition Builder Action: Set client state / call API using event.payload.value ``` **Example anti-pattern (race-prone):** ``` Trigger: Button clicked Action: Read client state (which may lag behind the last encode) ``` Related Problem: PRB1900095