@mastra/dynamodb 1.0.1 → 1.0.2-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @mastra/dynamodb
2
2
 
3
+ ## 1.0.2-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Added atomic `updateWorkflowResults` and `updateWorkflowState` to safely merge concurrent step results into workflow snapshots. ([#12575](https://github.com/mastra-ai/mastra/pull/12575))
8
+
9
+ - Updated dependencies [[`504fc8b`](https://github.com/mastra-ai/mastra/commit/504fc8b9d0ddab717577ad3bf9c95ea4bd5377bd), [`f9c150b`](https://github.com/mastra-ai/mastra/commit/f9c150b7595ad05ad9cc9a11098e2944361e8c22), [`88de7e8`](https://github.com/mastra-ai/mastra/commit/88de7e8dfe4b7e1951a9e441bb33136e705ce24e), [`edee4b3`](https://github.com/mastra-ai/mastra/commit/edee4b37dff0af515fc7cc0e8d71ee39e6a762f0), [`3790c75`](https://github.com/mastra-ai/mastra/commit/3790c7578cc6a47d854eb12d89e6b1912867fe29), [`e7a235b`](https://github.com/mastra-ai/mastra/commit/e7a235be6472e0c870ed6c791ddb17c492dc188b), [`d51d298`](https://github.com/mastra-ai/mastra/commit/d51d298953967aab1f58ec965b644d109214f085), [`6dbeeb9`](https://github.com/mastra-ai/mastra/commit/6dbeeb94a8b1eebb727300d1a98961f882180794), [`d5f0d8d`](https://github.com/mastra-ai/mastra/commit/d5f0d8d6a03e515ddaa9b5da19b7e44b8357b07b), [`09c3b18`](https://github.com/mastra-ai/mastra/commit/09c3b1802ff14e243a8a8baea327440bc8cc2e32), [`b896379`](https://github.com/mastra-ai/mastra/commit/b8963791c6afa79484645fcec596a201f936b9a2), [`85c84eb`](https://github.com/mastra-ai/mastra/commit/85c84ebb78aebfcba9d209c8e152b16d7a00cb71), [`a89272a`](https://github.com/mastra-ai/mastra/commit/a89272a5d71939b9fcd284e6a6dc1dd091a6bdcf), [`ee9c8df`](https://github.com/mastra-ai/mastra/commit/ee9c8df644f19d055af5f496bf4942705f5a47b7), [`77b4a25`](https://github.com/mastra-ai/mastra/commit/77b4a254e51907f8ff3a3ba95596a18e93ae4b35), [`276246e`](https://github.com/mastra-ai/mastra/commit/276246e0b9066a1ea48bbc70df84dbe528daaf99), [`08ecfdb`](https://github.com/mastra-ai/mastra/commit/08ecfdbdad6fb8285deef86a034bdf4a6047cfca), [`d5f628c`](https://github.com/mastra-ai/mastra/commit/d5f628ca86c6f6f3ff1035d52f635df32dd81cab), [`524c0f3`](https://github.com/mastra-ai/mastra/commit/524c0f3c434c3d9d18f66338dcef383d6161b59c), [`c18a0e9`](https://github.com/mastra-ai/mastra/commit/c18a0e9cef1e4ca004b2963d35e4cfc031971eac), [`4bd21ea`](https://github.com/mastra-ai/mastra/commit/4bd21ea43d44d0a0427414fc047577f9f0aa3bec), [`115a7a4`](https://github.com/mastra-ai/mastra/commit/115a7a47db5e9896fec12ae6507501adb9ec89bf), [`22a48ae`](https://github.com/mastra-ai/mastra/commit/22a48ae2513eb54d8d79dad361fddbca97a155e8), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9311c17`](https://github.com/mastra-ai/mastra/commit/9311c17d7a0640d9c4da2e71b814dc67c57c6369), [`7edf78f`](https://github.com/mastra-ai/mastra/commit/7edf78f80422c43e84585f08ba11df0d4d0b73c5), [`1c4221c`](https://github.com/mastra-ai/mastra/commit/1c4221cf6032ec98d0e094d4ee11da3e48490d96), [`d25b9ea`](https://github.com/mastra-ai/mastra/commit/d25b9eabd400167255a97b690ffbc4ee4097ded5), [`fe1ce5c`](https://github.com/mastra-ai/mastra/commit/fe1ce5c9211c03d561606fda95cbfe7df1d9a9b5), [`b03c0e0`](https://github.com/mastra-ai/mastra/commit/b03c0e0389a799523929a458b0509c9e4244d562), [`0a8366b`](https://github.com/mastra-ai/mastra/commit/0a8366b0a692fcdde56c4d526e4cf03c502ae4ac), [`85664e9`](https://github.com/mastra-ai/mastra/commit/85664e9fd857320fbc245e301f764f45f66f32a3), [`bc79650`](https://github.com/mastra-ai/mastra/commit/bc796500c6e0334faa158a96077e3fb332274869), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`3a3a59e`](https://github.com/mastra-ai/mastra/commit/3a3a59e8ffaa6a985fe3d9a126a3f5ade11a6724), [`3108d4e`](https://github.com/mastra-ai/mastra/commit/3108d4e649c9fddbf03253a6feeb388a5fa9fa5a), [`0c33b2c`](https://github.com/mastra-ai/mastra/commit/0c33b2c9db537f815e1c59e2c898ffce2e395a79), [`191e5bd`](https://github.com/mastra-ai/mastra/commit/191e5bd29b82f5bda35243945790da7bc7b695c2), [`f77cd94`](https://github.com/mastra-ai/mastra/commit/f77cd94c44eabed490384e7d19232a865e13214c), [`e8135c7`](https://github.com/mastra-ai/mastra/commit/e8135c7e300dac5040670eec7eab896ac6092e30), [`daca48f`](https://github.com/mastra-ai/mastra/commit/daca48f0fb17b7ae0b62a2ac40cf0e491b2fd0b7), [`257d14f`](https://github.com/mastra-ai/mastra/commit/257d14faca5931f2e4186fc165b6f0b1f915deee), [`352f25d`](https://github.com/mastra-ai/mastra/commit/352f25da316b24cdd5b410fd8dddf6a8b763da2a), [`93477d0`](https://github.com/mastra-ai/mastra/commit/93477d0769b8a13ea5ed73d508d967fb23eaeed9), [`31c78b3`](https://github.com/mastra-ai/mastra/commit/31c78b3eb28f58a8017f1dcc795c33214d87feac), [`0bc0720`](https://github.com/mastra-ai/mastra/commit/0bc07201095791858087cc56f353fcd65e87ab54), [`36516ac`](https://github.com/mastra-ai/mastra/commit/36516aca1021cbeb42e74751b46a2614101f37c8), [`e947652`](https://github.com/mastra-ai/mastra/commit/e9476527fdecb4449e54570e80dfaf8466901254), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`ec248f6`](https://github.com/mastra-ai/mastra/commit/ec248f6b56e8a037c066c49b2178e2507471d988)]:
10
+ - @mastra/core@1.9.0-alpha.0
11
+
3
12
  ## 1.0.1
4
13
 
5
14
  ### Patch Changes
package/LICENSE.md CHANGED
@@ -1,3 +1,18 @@
1
+ Portions of this software are licensed as follows:
2
+
3
+ - All content that resides under any directory named "ee/" within this
4
+ repository, including but not limited to:
5
+ - `packages/core/src/auth/ee/`
6
+ - `packages/server/src/server/auth/ee/`
7
+ is licensed under the license defined in `ee/LICENSE`.
8
+
9
+ - All third-party components incorporated into the Mastra Software are
10
+ licensed under the original license provided by the owner of the
11
+ applicable component.
12
+
13
+ - Content outside of the above-mentioned directories or restrictions is
14
+ available under the "Apache License 2.0" as defined below.
15
+
1
16
  # Apache License 2.0
2
17
 
3
18
  Copyright (c) 2025 Kepler Software, Inc.
@@ -3,7 +3,7 @@ name: mastra-dynamodb
3
3
  description: Documentation for @mastra/dynamodb. Use when working with @mastra/dynamodb APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/dynamodb"
6
- version: "1.0.1"
6
+ version: "1.0.2-alpha.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.1",
2
+ "version": "1.0.2-alpha.0",
3
3
  "package": "@mastra/dynamodb",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -53,19 +53,19 @@ Detailed instructions for setting up the table using AWS CloudFormation or AWS C
53
53
  ### Basic Usage
54
54
 
55
55
  ```typescript
56
- import { Memory } from "@mastra/memory";
57
- import { DynamoDBStore } from "@mastra/dynamodb";
56
+ import { Memory } from '@mastra/memory'
57
+ import { DynamoDBStore } from '@mastra/dynamodb'
58
58
 
59
59
  // Initialize the DynamoDB storage
60
60
  const storage = new DynamoDBStore({
61
- id: "dynamodb", // Unique identifier for this storage instance
61
+ id: 'dynamodb', // Unique identifier for this storage instance
62
62
  config: {
63
- tableName: "mastra-single-table", // Name of your DynamoDB table
64
- region: "us-east-1", // Optional: AWS region, defaults to 'us-east-1'
63
+ tableName: 'mastra-single-table', // Name of your DynamoDB table
64
+ region: 'us-east-1', // Optional: AWS region, defaults to 'us-east-1'
65
65
  // endpoint: "http://localhost:8000", // Optional: For local DynamoDB
66
66
  // credentials: { accessKeyId: "YOUR_ACCESS_KEY", secretAccessKey: "YOUR_SECRET_KEY" } // Optional
67
67
  },
68
- });
68
+ })
69
69
 
70
70
  // Example: Initialize Memory with DynamoDB storage
71
71
  const memory = new Memory({
@@ -73,7 +73,7 @@ const memory = new Memory({
73
73
  options: {
74
74
  lastMessages: 10,
75
75
  },
76
- });
76
+ })
77
77
  ```
78
78
 
79
79
  ### Local Development with DynamoDB Local
@@ -89,19 +89,19 @@ For local development, you can use [DynamoDB Local](https://docs.aws.amazon.com/
89
89
  2. **Configure `DynamoDBStore` to use the local endpoint:**
90
90
 
91
91
  ```typescript
92
- import { DynamoDBStore } from "@mastra/dynamodb";
92
+ import { DynamoDBStore } from '@mastra/dynamodb'
93
93
 
94
94
  const storage = new DynamoDBStore({
95
- id: "dynamodb-local",
95
+ id: 'dynamodb-local',
96
96
  config: {
97
- tableName: "mastra-single-table", // Ensure this table is created in your local DynamoDB
98
- region: "localhost", // Can be any string for local, 'localhost' is common
99
- endpoint: "http://localhost:8000",
97
+ tableName: 'mastra-single-table', // Ensure this table is created in your local DynamoDB
98
+ region: 'localhost', // Can be any string for local, 'localhost' is common
99
+ endpoint: 'http://localhost:8000',
100
100
  // For DynamoDB Local, credentials are not typically required unless configured.
101
101
  // If you've configured local credentials:
102
102
  // credentials: { accessKeyId: "fakeMyKeyId", secretAccessKey: "fakeSecretAccessKey" }
103
103
  },
104
- });
104
+ })
105
105
  ```
106
106
 
107
107
  You will still need to create the table and GSIs in your local DynamoDB instance, for example, using the AWS CLI pointed to your local endpoint.
@@ -137,13 +137,13 @@ To use TTL, you must:
137
137
  2. **Enable TTL on your DynamoDB table** via AWS Console or CLI, specifying the attribute name (default: `ttl`)
138
138
 
139
139
  ```typescript
140
- import { DynamoDBStore } from "@mastra/dynamodb";
140
+ import { DynamoDBStore } from '@mastra/dynamodb'
141
141
 
142
142
  const storage = new DynamoDBStore({
143
- name: "dynamodb",
143
+ name: 'dynamodb',
144
144
  config: {
145
- tableName: "mastra-single-table",
146
- region: "us-east-1",
145
+ tableName: 'mastra-single-table',
146
+ region: 'us-east-1',
147
147
  ttl: {
148
148
  // Messages expire after 30 days
149
149
  message: {
@@ -158,7 +158,7 @@ const storage = new DynamoDBStore({
158
158
  // Traces expire after 7 days with custom attribute name
159
159
  trace: {
160
160
  enabled: true,
161
- attributeName: "expiresAt", // Custom TTL attribute
161
+ attributeName: 'expiresAt', // Custom TTL attribute
162
162
  defaultTtlSeconds: 7 * 24 * 60 * 60, // 7 days
163
163
  },
164
164
  // Workflow snapshots don't expire
@@ -167,7 +167,7 @@ const storage = new DynamoDBStore({
167
167
  },
168
168
  },
169
169
  },
170
- });
170
+ })
171
171
  ```
172
172
 
173
173
  ### Supported Entity Types
@@ -214,7 +214,7 @@ aws dynamodb update-time-to-live \
214
214
  4. Under "Time to Live (TTL)", click "Manage TTL"
215
215
  5. Enable TTL and specify the attribute name (default: `ttl`)
216
216
 
217
- > **Note**: DynamoDB deletes expired items within 48 hours after expiration. Items remain queryable until actually deleted.
217
+ > **Note:** DynamoDB deletes expired items within 48 hours after expiration. Items remain queryable until actually deleted.
218
218
 
219
219
  ## AWS IAM Permissions
220
220
 
package/dist/index.cjs CHANGED
@@ -2144,6 +2144,8 @@ function formatWorkflowRun(snapshotData) {
2144
2144
  resourceId: snapshotData.resourceId
2145
2145
  };
2146
2146
  }
2147
+ var MAX_RETRIES = 5;
2148
+ var BASE_DELAY_MS = 50;
2147
2149
  var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2148
2150
  service;
2149
2151
  ttlConfig;
@@ -2153,9 +2155,41 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2153
2155
  this.service = resolved.service;
2154
2156
  this.ttlConfig = resolved.ttl;
2155
2157
  }
2158
+ supportsConcurrentUpdates() {
2159
+ return true;
2160
+ }
2156
2161
  async dangerouslyClearAll() {
2157
2162
  await deleteTableData(this.service, storage.TABLE_WORKFLOW_SNAPSHOT);
2158
2163
  }
2164
+ /**
2165
+ * Helper to check if an error is a DynamoDB conditional check failure
2166
+ */
2167
+ isConditionalCheckFailed(error) {
2168
+ if (error && typeof error === "object") {
2169
+ const err = error;
2170
+ if (err.name === "ConditionalCheckFailedException" || err.code === "ConditionalCheckFailedException" || (err.__type?.includes("ConditionalCheckFailedException") ?? false)) {
2171
+ return true;
2172
+ }
2173
+ if (err.message?.includes("conditional request failed")) {
2174
+ return true;
2175
+ }
2176
+ if (err.cause && typeof err.cause === "object") {
2177
+ const cause = err.cause;
2178
+ if (cause.name === "ConditionalCheckFailedException" || cause.code === "ConditionalCheckFailedException") {
2179
+ return true;
2180
+ }
2181
+ }
2182
+ }
2183
+ return false;
2184
+ }
2185
+ /**
2186
+ * Helper to delay with exponential backoff and jitter
2187
+ */
2188
+ async delay(attempt) {
2189
+ const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
2190
+ const jitter = Math.random() * backoff * 0.5;
2191
+ await new Promise((resolve) => setTimeout(resolve, backoff + jitter));
2192
+ }
2159
2193
  async updateWorkflowResults({
2160
2194
  workflowName,
2161
2195
  runId,
@@ -2163,69 +2197,147 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2163
2197
  result,
2164
2198
  requestContext
2165
2199
  }) {
2166
- try {
2167
- const existingSnapshot = await this.loadWorkflowSnapshot({ workflowName, runId });
2168
- let snapshot;
2169
- if (!existingSnapshot) {
2170
- snapshot = {
2171
- context: {},
2172
- activePaths: [],
2173
- timestamp: Date.now(),
2174
- suspendedPaths: {},
2175
- activeStepsPath: {},
2176
- resumeLabels: {},
2177
- serializedStepGraph: [],
2178
- status: "pending",
2179
- value: {},
2180
- waitingPaths: {},
2181
- runId,
2182
- requestContext: {}
2200
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
2201
+ try {
2202
+ const existingRecord = await this.service.entities.workflow_snapshot.get({
2203
+ entity: "workflow_snapshot",
2204
+ workflow_name: workflowName,
2205
+ run_id: runId
2206
+ }).go();
2207
+ const now = /* @__PURE__ */ new Date();
2208
+ let snapshot;
2209
+ let previousUpdatedAt;
2210
+ if (!existingRecord.data) {
2211
+ snapshot = {
2212
+ context: {},
2213
+ activePaths: [],
2214
+ timestamp: Date.now(),
2215
+ suspendedPaths: {},
2216
+ activeStepsPath: {},
2217
+ resumeLabels: {},
2218
+ serializedStepGraph: [],
2219
+ status: "pending",
2220
+ value: {},
2221
+ waitingPaths: {},
2222
+ runId,
2223
+ requestContext: {}
2224
+ };
2225
+ } else {
2226
+ snapshot = existingRecord.data.snapshot;
2227
+ previousUpdatedAt = existingRecord.data.updatedAt;
2228
+ }
2229
+ snapshot.context[stepId] = result;
2230
+ snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
2231
+ const data = {
2232
+ entity: "workflow_snapshot",
2233
+ workflow_name: workflowName,
2234
+ run_id: runId,
2235
+ snapshot: JSON.stringify(snapshot),
2236
+ createdAt: existingRecord.data?.createdAt ?? now.toISOString(),
2237
+ updatedAt: now.toISOString(),
2238
+ ...getTtlProps("workflow_snapshot", this.ttlConfig)
2183
2239
  };
2184
- } else {
2185
- snapshot = existingSnapshot;
2240
+ if (previousUpdatedAt) {
2241
+ await this.service.entities.workflow_snapshot.upsert(data).where((attr, op) => op.eq(attr.updatedAt, previousUpdatedAt)).go();
2242
+ } else {
2243
+ await this.service.entities.workflow_snapshot.create(data).where((attr, op) => op.notExists(attr.run_id)).go();
2244
+ }
2245
+ return snapshot.context;
2246
+ } catch (error$1) {
2247
+ if (this.isConditionalCheckFailed(error$1)) {
2248
+ if (attempt < MAX_RETRIES - 1) {
2249
+ this.logger.debug(
2250
+ `Optimistic locking conflict in updateWorkflowResults, retrying (attempt ${attempt + 1})`
2251
+ );
2252
+ await this.delay(attempt);
2253
+ continue;
2254
+ }
2255
+ }
2256
+ if (error$1 instanceof error.MastraError) throw error$1;
2257
+ throw new error.MastraError(
2258
+ {
2259
+ id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_RESULTS", "FAILED"),
2260
+ domain: error.ErrorDomain.STORAGE,
2261
+ category: error.ErrorCategory.THIRD_PARTY,
2262
+ details: { workflowName, runId, stepId }
2263
+ },
2264
+ error$1
2265
+ );
2186
2266
  }
2187
- snapshot.context[stepId] = result;
2188
- snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
2189
- await this.persistWorkflowSnapshot({ workflowName, runId, snapshot });
2190
- return snapshot.context;
2191
- } catch (error$1) {
2192
- if (error$1 instanceof error.MastraError) throw error$1;
2193
- throw new error.MastraError(
2194
- {
2195
- id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_RESULTS", "FAILED"),
2196
- domain: error.ErrorDomain.STORAGE,
2197
- category: error.ErrorCategory.THIRD_PARTY,
2198
- details: { workflowName, runId, stepId }
2199
- },
2200
- error$1
2201
- );
2202
2267
  }
2268
+ throw new error.MastraError(
2269
+ {
2270
+ id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_RESULTS", "MAX_RETRIES_EXCEEDED"),
2271
+ domain: error.ErrorDomain.STORAGE,
2272
+ category: error.ErrorCategory.THIRD_PARTY,
2273
+ details: { workflowName, runId, stepId }
2274
+ },
2275
+ new Error("Max retries exceeded for optimistic locking")
2276
+ );
2203
2277
  }
2204
2278
  async updateWorkflowState({
2205
2279
  workflowName,
2206
2280
  runId,
2207
2281
  opts
2208
2282
  }) {
2209
- try {
2210
- const existingSnapshot = await this.loadWorkflowSnapshot({ workflowName, runId });
2211
- if (!existingSnapshot || !existingSnapshot.context) {
2212
- return void 0;
2283
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
2284
+ try {
2285
+ const existingRecord = await this.service.entities.workflow_snapshot.get({
2286
+ entity: "workflow_snapshot",
2287
+ workflow_name: workflowName,
2288
+ run_id: runId
2289
+ }).go();
2290
+ if (!existingRecord.data) {
2291
+ return void 0;
2292
+ }
2293
+ const existingSnapshot = existingRecord.data.snapshot;
2294
+ if (!existingSnapshot || !existingSnapshot.context) {
2295
+ return void 0;
2296
+ }
2297
+ const previousUpdatedAt = existingRecord.data.updatedAt;
2298
+ const updatedSnapshot = { ...existingSnapshot, ...opts };
2299
+ const now = /* @__PURE__ */ new Date();
2300
+ const data = {
2301
+ entity: "workflow_snapshot",
2302
+ workflow_name: workflowName,
2303
+ run_id: runId,
2304
+ snapshot: JSON.stringify(updatedSnapshot),
2305
+ createdAt: existingRecord.data.createdAt,
2306
+ updatedAt: now.toISOString(),
2307
+ resourceId: existingRecord.data.resourceId,
2308
+ ...getTtlProps("workflow_snapshot", this.ttlConfig)
2309
+ };
2310
+ await this.service.entities.workflow_snapshot.upsert(data).where((attr, op) => op.eq(attr.updatedAt, previousUpdatedAt)).go();
2311
+ return updatedSnapshot;
2312
+ } catch (error$1) {
2313
+ if (this.isConditionalCheckFailed(error$1)) {
2314
+ if (attempt < MAX_RETRIES - 1) {
2315
+ this.logger.debug(`Optimistic locking conflict in updateWorkflowState, retrying (attempt ${attempt + 1})`);
2316
+ await this.delay(attempt);
2317
+ continue;
2318
+ }
2319
+ }
2320
+ if (error$1 instanceof error.MastraError) throw error$1;
2321
+ throw new error.MastraError(
2322
+ {
2323
+ id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_STATE", "FAILED"),
2324
+ domain: error.ErrorDomain.STORAGE,
2325
+ category: error.ErrorCategory.THIRD_PARTY,
2326
+ details: { workflowName, runId }
2327
+ },
2328
+ error$1
2329
+ );
2213
2330
  }
2214
- const updatedSnapshot = { ...existingSnapshot, ...opts };
2215
- await this.persistWorkflowSnapshot({ workflowName, runId, snapshot: updatedSnapshot });
2216
- return updatedSnapshot;
2217
- } catch (error$1) {
2218
- if (error$1 instanceof error.MastraError) throw error$1;
2219
- throw new error.MastraError(
2220
- {
2221
- id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_STATE", "FAILED"),
2222
- domain: error.ErrorDomain.STORAGE,
2223
- category: error.ErrorCategory.THIRD_PARTY,
2224
- details: { workflowName, runId }
2225
- },
2226
- error$1
2227
- );
2228
2331
  }
2332
+ throw new error.MastraError(
2333
+ {
2334
+ id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_STATE", "MAX_RETRIES_EXCEEDED"),
2335
+ domain: error.ErrorDomain.STORAGE,
2336
+ category: error.ErrorCategory.THIRD_PARTY,
2337
+ details: { workflowName, runId }
2338
+ },
2339
+ new Error("Max retries exceeded for optimistic locking")
2340
+ );
2229
2341
  }
2230
2342
  // Workflow operations
2231
2343
  async persistWorkflowSnapshot({