From fb561c3e1fded110afb908059df8412ecbff5f18 Mon Sep 17 00:00:00 2001 From: Rhys Sullivan <39114868+RhysSullivan@users.noreply.github.com> Date: Sun, 28 Jun 2026 15:25:53 -0700 Subject: [PATCH] fix(cloud): create SQLite DO without deleting the old class in the same deploy The delete migration kept failing (code 10061): Cloudflare validates a class delete against the LIVE binding, which still pointed at McpSessionDO, so binding move + delete can't happen in one deploy. Drop the delete: v2 only creates the new SQLite class McpSessionDOSqlite and the MCP_SESSION binding moves to it. The old KV McpSessionDO is left orphaned (kept as a stub export so the migration stays valid) and can be deleted in a later deploy now that nothing binds it. Also repoint the generated MCP_SESSION binding type to McpSessionDOSqlite. --- apps/cloud/src/server.ts | 9 +++++++++ apps/cloud/worker-configuration.d.ts | 2 +- apps/cloud/wrangler.jsonc | 15 ++++++++------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/apps/cloud/src/server.ts b/apps/cloud/src/server.ts index 0e400cbe7..9697cde78 100644 --- a/apps/cloud/src/server.ts +++ b/apps/cloud/src/server.ts @@ -1,3 +1,4 @@ +import { DurableObject } from "cloudflare:workers"; import { SpanKind, SpanStatusCode, context, trace } from "@opentelemetry/api"; import { ATTR_HTTP_REQUEST_METHOD, @@ -46,6 +47,14 @@ export const McpSessionDOSqlite = Sentry.instrumentDurableObjectWithSentry( McpSessionDOBase, ); +// Orphaned placeholder for the original key-value `McpSessionDO` class (migration +// v1). The live MCP session DO is now `McpSessionDOSqlite` (SQLite); the +// `MCP_SESSION` binding moved to it. Cloudflare won't delete `McpSessionDO` in the +// same deploy that moves its binding, so the class is left unbound and is kept +// exported here only to satisfy the migration. It can be removed in a later deploy +// (with a `deleted_classes: ["McpSessionDO"]` migration) now that nothing binds it. +export class McpSessionDO extends DurableObject {} + // --------------------------------------------------------------------------- // Worker fetch handler // diff --git a/apps/cloud/worker-configuration.d.ts b/apps/cloud/worker-configuration.d.ts index dfb7cc176..ca9829112 100644 --- a/apps/cloud/worker-configuration.d.ts +++ b/apps/cloud/worker-configuration.d.ts @@ -14,7 +14,7 @@ declare namespace Cloudflare { WORKOS_COOKIE_PASSWORD: string; APP_URL: string; WORKOS_CLAIM_TOKEN: string; - MCP_SESSION: DurableObjectNamespace; + MCP_SESSION: DurableObjectNamespace; MARKETING: Fetcher /* executor-marketing */; } } diff --git a/apps/cloud/wrangler.jsonc b/apps/cloud/wrangler.jsonc index f2cc4a143..68ca6297a 100644 --- a/apps/cloud/wrangler.jsonc +++ b/apps/cloud/wrangler.jsonc @@ -25,12 +25,14 @@ ], }, // The MCP session DO moved to the Cloudflare Agents (`McpAgent`) base, which - // stores state in SQLite. The original `McpSessionDO` was created with the - // key-value backend (`new_classes`), and Cloudflare cannot convert a live class - // to SQLite in place, nor delete a class while a binding still references it. - // Session state is ephemeral, so v2 repoints the `MCP_SESSION` binding to a new - // SQLite-backed class (`McpSessionDOSqlite`) and deletes the old KV `McpSessionDO` - // (now unreferenced). The worker exports `McpSessionDOSqlite`, not `McpSessionDO`. + // stores state in SQLite. The original `McpSessionDO` was created on the + // key-value backend (`new_classes`) and cannot be converted in place. Cloudflare + // also refuses to delete a class in the same deploy that moves its binding (it + // validates the delete against the live binding), so v2 only CREATES the new + // SQLite class `McpSessionDOSqlite` and the `MCP_SESSION` binding moves to it. + // The old KV `McpSessionDO` is left orphaned (unbound, kept as a stub export in + // server.ts so the migration stays valid); it can be deleted in a later deploy + // now that nothing binds it. Session state is ephemeral, so nothing is lost. "migrations": [ { "tag": "v1", @@ -38,7 +40,6 @@ }, { "tag": "v2", - "deleted_classes": ["McpSessionDO"], "new_sqlite_classes": ["McpSessionDOSqlite"], }, ],