{"record":{"id":"5fe3557f35aa04e3","repo":"mastra-ai/mastra","slug":"harness-pending-item-item-id-already-exists-o","errorCode":null,"errorMessage":"Harness pending item \"${item.id}\" already exists on session \"${sessionId}\"","messagePattern":"Harness pending item \"(.+?)\" already exists on session \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/harness/base.ts","lineNumber":42,"sourceCode":"    const next: SessionRecord = {\n      ...record,\n      ...updates,\n      id: record.id,\n      createdAt: record.createdAt,\n      lastActivityAt: updates.lastActivityAt ?? new Date(),\n    };\n    await this.saveSession(next);\n    return next;\n  }\n\n  async appendPendingItem(sessionId: string, item: HarnessPendingItemRecord): Promise<SessionRecord> {\n    const record = await this.loadSession(sessionId);\n    if (!record) {\n      throw new Error(`Harness session \"${sessionId}\" was not found`);\n    }\n\n    if (record.pending?.some(existing => existing.id === item.id)) {\n      throw new Error(`Harness pending item \"${item.id}\" already exists on session \"${sessionId}\"`);\n    }\n\n    return this.updateSession(sessionId, {\n      pending: [...(record.pending ?? []), item],\n    });\n  }\n\n  async updatePendingItem(\n    sessionId: string,\n    pendingItemId: string,\n    updates: Partial<Omit<HarnessPendingItemRecord, 'id' | 'sessionId' | 'createdAt'>>,\n  ): Promise<SessionRecord> {\n    const record = await this.loadSession(sessionId);\n    if (!record) {\n      throw new Error(`Harness session \"${sessionId}\" was not found`);\n    }\n\n    let found = false;","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/harness/base.ts#L24-L60","documentation":"`appendPendingItem` throws this when the target session already contains a pending item with the same `item.id`. The library enforces unique pending-item ids per session to avoid duplicate work items.","triggerScenarios":"Calling `appendPendingItem(sessionId, item)` where `record.pending` already contains an entry whose `id === item.id` — typically retrying an append after a timeout, or a client generating non-unique ids.","commonSituations":"Idempotent retry logic that re-sends the same item without checking; crash-recovery replay of a message queue; code that constructs item ids from non-unique fields (timestamps at second granularity, fixed strings like 'plan').","solutions":["Generate a unique id per pending item (crypto.randomUUID() or an incrementing per-session counter).","Check `record.pending` (via `loadSession`) for an existing item with the id before appending.","Switch to `updatePendingItem` when the intent is to modify an existing item rather than add a new one.","Make retry wrappers idempotent: catch this error and treat the append as already-done if the existing item matches."],"exampleFix":"// before\nawait storage.appendPendingItem(sessionId, { id: 'tool-call', /* ... */ }); // throws on retry\n// after\nawait storage.appendPendingItem(sessionId, { id: crypto.randomUUID(), /* ... */ });","handlingStrategy":"validation","validationCode":"const record = await storage.loadSession(sessionId);\nif (record?.pending?.some(i => i.id === item.id)) {\n  return; // already appended — idempotent no-op\n}\nawait storage.appendPendingItem(sessionId, item);","typeGuard":"function isPendingItem(x: unknown): x is HarnessPendingItemRecord {\n  return typeof x === 'object' && x !== null && typeof (x as any).id === 'string';\n}","tryCatchPattern":"try {\n  await storage.appendPendingItem(sessionId, item);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('already exists')) {\n    return; // treat as success for idempotent retries\n  }\n  throw e;\n}","preventionTips":["Generate item ids with crypto.randomUUID() instead of derived/fixed strings.","Design retries as idempotent: catch 'already exists' and continue.","Use updatePendingItem when modifying an existing item, not append.","Scope item ids to the session (prefix with sessionId if reused across sessions)."],"tags":["storage","harness","duplicate-id","pending-items"],"backgroundTag":"duplicate-key-conflict","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}