Skip to content

fix(cloudflare): adopt durable object classes created outside alchemy#495

Open
sam-goodwin wants to merge 2 commits into
mainfrom
claude/priceless-germain-0590ed
Open

fix(cloudflare): adopt durable object classes created outside alchemy#495
sam-goodwin wants to merge 2 commits into
mainfrom
claude/priceless-germain-0590ed

Conversation

@sam-goodwin

Copy link
Copy Markdown
Contributor

Cloudflare.Worker already adopts the worker itself, but its Durable Object class migrations only mapped logical-id→class through alchemy:do: tags. A worker created outside Alchemy (raw API, Wrangler, dashboard) has no such tags, so on the adopting deploy every DO class fell into newSqliteClasses — asking Cloudflare to create a class that already exists, which fails the migration.

Fall back to matching the observed cloud binding by binding name (mirrors the original vendor behavior), so an existing class is reused — or renamed if the class name differs — instead of recreated.

let previousClassName = oldDoClassNameByLogicalId[binding.logicalId];
if (!previousClassName) {
  const observed = oldBindings.find(
    (old) => old.type === "durable_object_namespace" &&
             old.className && old.name === binding.bindingName,
  );
  if (observed?.className) previousClassName = observed.className;
}

Limitation (by design): on the adopting deploy the binding's class name must match the existing class. Once Alchemy writes the alchemy:do: tag, later renames are driven by logical id.

Test provisions a worker + Counter SQLite DO class straight through workers.putScript (no Alchemy tags), then deploys an async inline-script Worker over the same name with adopt(true) and round-trips an increment through the reused class. Verified live, alongside the existing class-migration test.

Closes #486

When adopting a worker not created by Alchemy (raw API/Wrangler/dashboard),
its Durable Object classes have no alchemy:do logical-id->class tag, so every
class fell into newSqliteClasses and Cloudflare rejected the migration for
trying to create a class that already exists. Fall back to matching the
observed cloud binding by binding name so the existing class is reused (or
renamed) instead of recreated.

Closes #486

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@alchemy-version-bot

alchemy-version-bot Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Install the packages built from this commit:

alchemy

bun add alchemy@https://pkg.ing/alchemy/65e518a

@alchemy.run/better-auth

bun add @alchemy.run/better-auth@https://pkg.ing/@alchemy.run/better-auth/65e518a

@alchemy.run/pr-package

bun add @alchemy.run/pr-package@https://pkg.ing/@alchemy.run/pr-package/65e518a

Add an "Adopting an Existing Durable Object" section to the
DurableObjectNamespace JSDoc explaining the binding-name fallback, the
one-time className-match constraint on the adopting deploy, and that
renames only work on subsequent deploys once the alchemy:do tag exists.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@alchemy-version-bot

alchemy-version-bot Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Website Preview Deployed

URL: https://alchemyeffectwebsite-worker-pr-495-mdl4c5cm7zs4cq3t.testing-2b2.workers.dev

Built from commit 65e518a.


This comment updates automatically with each push.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cloudflare DO adoption

1 participant