Skip to content

Commit 14de55b

Browse files
fix: Rewrite activeClusterSelectionPolicy schema to remove legacy fields & handle empty policy (#1351)
## Summary [v1.4.0 of Cadence](https://github.com/cadence-workflow/cadence/releases/tag/v1.4.0) introduces Active-Active Domains, which brings with it the concept of starting workflows with a special Active Cluster Selection Policy. However, when starting a workflow, users can specify an empty Active Cluster Selection Policy, which the Cadence UI fails to parse and render appropriately (#1344). This PR fixes that by: - Fixing the schema to account for an empty ActiveClusterSelectionPolicy - Pulling in the latest Cadence IDL changes, including cadence-workflow/cadence-idl#264 - This allows us to clean up the legacy active-active implementation on our side as well ## Test plan Ran locally. ### Before <img width="2559" height="658" alt="Screenshot 2026-06-11 at 15 41 56" src="https://github.com/user-attachments/assets/f11a50b4-1d36-4ad2-9d6e-a1ecdfed0b20" /> ### After <img width="1645" height="1186" alt="Screenshot 2026-06-12 at 14 16 29" src="https://github.com/user-attachments/assets/cf4ea181-ffa6-432a-ae10-cdb9b336cc69" /> ## Notes Fixes #1344 --------- Signed-off-by: Adhitya Mamallan <adhitya.mamallan@uber.com>
1 parent 3a31a75 commit 14de55b

3 files changed

Lines changed: 14 additions & 43 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "cadence-web",
33
"private": true,
44
"config": {
5-
"cadence_idl_version": "8bcf2d71101b757ee820e2d05249deec9f4dddca"
5+
"cadence_idl_version": "3ee08a98cf704ed8b2cc2101abe71ab80eccf542"
66
},
77
"scripts": {
88
"dev": "CADENCE_WEB_PORT=${CADENCE_WEB_PORT:-8088} next dev -p ${CADENCE_WEB_PORT:-8088} -H ${CADENCE_WEB_HOSTNAME:-0.0.0.0} | pino-pretty --messageKey message",

src/route-handlers/list-workflows/helpers/__tests__/get-workflow-list-item-from-execution.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ describe('getWorkflowListItemFromExecution', () => {
7171
const execution: WorkflowExecutionInfo = {
7272
...BASE_EXECUTION,
7373
activeClusterSelectionPolicy: {
74-
strategy: 'ACTIVE_CLUSTER_SELECTION_STRATEGY_INVALID',
75-
strategyConfig: 'activeClusterStickyRegionConfig',
7674
clusterAttribute: {
7775
scope: 'mock-scope',
7876
name: 'mock-cluster-name',

src/utils/data-formatters/schema/history-event-schema.ts

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { z } from 'zod';
22

33
import { type ActiveClusterSelectionPolicy } from '@/__generated__/proto-ts/uber/cadence/api/v1/ActiveClusterSelectionPolicy';
4-
import { ActiveClusterSelectionStrategy } from '@/__generated__/proto-ts/uber/cadence/api/v1/ActiveClusterSelectionStrategy';
54
import { CancelExternalWorkflowExecutionFailedCause } from '@/__generated__/proto-ts/uber/cadence/api/v1/CancelExternalWorkflowExecutionFailedCause';
65
import { ChildWorkflowExecutionFailedCause } from '@/__generated__/proto-ts/uber/cadence/api/v1/ChildWorkflowExecutionFailedCause';
76
import { ContinueAsNewInitiator } from '@/__generated__/proto-ts/uber/cadence/api/v1/ContinueAsNewInitiator';
@@ -148,46 +147,20 @@ const clusterAttributeSchema = z.object({
148147
name: z.string(),
149148
});
150149

151-
// TODO @adhitya.mamallan - this needs to be removed as part of active-active's redesign, once the IDL has removed them
152-
const activeClusterSelectionStrategySchema = z.enum([
153-
ActiveClusterSelectionStrategy.ACTIVE_CLUSTER_SELECTION_STRATEGY_INVALID,
154-
ActiveClusterSelectionStrategy.ACTIVE_CLUSTER_SELECTION_STRATEGY_REGION_STICKY,
155-
ActiveClusterSelectionStrategy.ACTIVE_CLUSTER_SELECTION_STRATEGY_EXTERNAL_ENTITY,
156-
]);
157-
158-
// The IDL still contains the strategy and strategyConfig fields, but they are absent
159-
// in the new active-active design. The preprocess step corrects this and allows us to
160-
// parse activeClusterSelectionPolicy even if the backend does not pass the deprecated fields.
161-
//
162-
// TODO @adhitya.mamallan - update this once the IDL has been updated
163-
const activeClusterSelectionPolicySchema = z.preprocess(
164-
(data) => {
165-
if (typeof data === 'object' && data !== null) {
166-
const dataWithDefaults = {
167-
...data,
168-
strategy:
169-
'strategy' in data && data.strategy
170-
? data.strategy
171-
: 'ACTIVE_CLUSTER_SELECTION_STRATEGY_INVALID',
172-
strategyConfig:
173-
'strategyConfig' in data && data.strategyConfig
174-
? data.strategyConfig
175-
: 'activeClusterStickyRegionConfig',
176-
};
177-
return dataWithDefaults;
178-
}
179-
return data;
180-
},
181-
z.object({
182-
clusterAttribute: clusterAttributeSchema,
183-
// TODO: remove the below fields once the IDL has removed them
184-
strategy: activeClusterSelectionStrategySchema,
185-
strategyConfig: z.enum([
186-
'activeClusterStickyRegionConfig',
187-
'activeClusterExternalEntityConfig',
188-
]),
150+
/**
151+
* In the active-active design the policy is identified solely by clusterAttribute, so a missing
152+
* or malformed payload carries no policy and falls back to null instead of failing the whole
153+
* history event.
154+
*
155+
* activeClusterSelectionPolicy and retryPolicy are the only object fields passed to StartWorkflow,
156+
* but activeClusterSelectionPolicy does not validate the request input type the way retryPolicy does.
157+
*/
158+
const activeClusterSelectionPolicySchema = z
159+
.object({
160+
clusterAttribute: clusterAttributeSchema.nullable(),
189161
})
190-
) as z.ZodType<ActiveClusterSelectionPolicy>;
162+
.nullable()
163+
.catch(null) as z.ZodType<ActiveClusterSelectionPolicy | null>;
191164

192165
const failureSchema = z.object({
193166
reason: z.string(),

0 commit comments

Comments
 (0)