Interactive Durable Objects migration assistant. Guides through new class creation, renaming, deletion, and transfer migrations with validation.
Guides through Durable Objects migrations with interactive validation and automatic configuration updates.
/plugin marketplace add secondsky/claude-skills/plugin install cloudflare-durable-objects@claude-skillsInteractive command to safely create and manage Durable Objects migrations. Handles new classes, renaming, deletion, and transfers with automatic validation and backup.
This command simplifies DO migration management by:
Before prompting user, analyze the current project state:
cat wrangler.jsonc
Parse configuration to extract:
Determine project state:
Case 1: No Existing Migrations
Case 2: Existing Migrations
Case 3: No DO Bindings
/do-setup firstShow user the current configuration:
Current Durable Objects Configuration:
Bindings:
- MY_DO → MyDurableObject
- CHAT_ROOM → ChatRoom
Migrations:
- v1: new_sqlite_classes [MyDurableObject]
- v2: new_sqlite_classes [ChatRoom]
Next migration tag: v3
Use AskUserQuestion tool to determine migration type and details:
Question: "What type of migration do you need to perform?" Header: "Migration Type" Options:
If user selected New Class, ask:
Question: "Which storage backend will this Durable Object use?" Header: "Storage Backend" Options:
Note: For other migration types, storage backend is already determined by existing class.
Gather class name(s) based on migration type:
Prompt: "Enter the name of the new Durable Object class to add:"
Show existing class names for reference:
Existing classes:
- MyDurableObject
- ChatRoom
New class name: _______
Validation:
Prompt 1: "Enter the current class name to rename:"
Show dropdown/autocomplete of existing class names:
Select class to rename:
> MyDurableObject
ChatRoom
Prompt 2: "Enter the new class name:"
Validation:
Prompt: "Enter the class name to delete:"
Show dropdown of existing classes with WARNING:
⚠️ WARNING: Deleting a class permanently destroys all DO instances and data!
Select class to delete:
> MyDurableObject
ChatRoom
This action cannot be undone. Continue? [y/N]
Require explicit confirmation due to data loss.
Prompt 1: "Enter the class name to transfer:"
Show existing classes:
Select class to transfer:
> MyDurableObject
ChatRoom
Prompt 2: "Enter the destination Worker script name:"
Current script: my-worker
Destination script: _______
Validation:
Question: "What tag should this migration use?" Header: "Migration Tag"
Suggested Tag: Auto-calculated based on existing migrations (e.g., v3)
Options:
If Custom Tag selected, prompt:
Enter custom migration tag: _______
Validation:
Before generating migration, perform validation checks:
For New Class migrations, verify class is exported:
# Check if class is exported in main file
grep "export class NEW_CLASS_NAME" src/index.ts
If not found:
⚠️ WARNING: Class 'MyNewDO' not found in src/index.ts
Before deploying, ensure:
export class MyNewDO extends DurableObject { ... }
Continue anyway? [y/N]
For New Class migrations, check if binding exists:
# Check wrangler.jsonc for binding
jq '.durable_objects.bindings[]? | select(.class_name == "NEW_CLASS_NAME")' wrangler.jsonc
If not found:
⚠️ WARNING: No binding found for class 'MyNewDO'
After migration, add to wrangler.jsonc:
"durable_objects": {
"bindings": [
{ "name": "MY_NEW_DO", "class_name": "MyNewDO" }
]
}
Continue? [y/N]
For Delete migrations, require triple confirmation:
⚠️ DESTRUCTIVE ACTION: Deleting class 'MyDurableObject'
This will:
1. Permanently delete ALL DO instances of this class
2. Destroy ALL data stored in these instances
3. Remove the class from production
Type the class name to confirm: _______
Type 'DELETE' to proceed: _______
Final confirmation [yes/NO]: _______
Only proceed if all three confirmations match.
Check for potential conflicts:
Sequential Tag Check:
Warning: Migration tag 'v5' but last migration was 'v2'
This creates a gap in versioning.
Recommended: Use sequential tags (v3, v4, v5...)
Continue with v5? [y/N]
Duplicate Class Check:
Error: Class 'MyDurableObject' already has migration in v1
Cannot create duplicate migration.
Options:
1. Use different class name
2. Cancel and review existing migrations
Create migration JSON based on type:
{
"tag": "MIGRATION_TAG",
"new_sqlite_classes": ["CLASS_NAME"]
}
Or for KV storage:
{
"tag": "MIGRATION_TAG",
"new_classes": ["CLASS_NAME"]
}
{
"tag": "MIGRATION_TAG",
"renamed_classes": [
{
"from": "OLD_CLASS_NAME",
"to": "NEW_CLASS_NAME"
}
]
}
{
"tag": "MIGRATION_TAG",
"deleted_classes": ["CLASS_NAME"]
}
{
"tag": "MIGRATION_TAG",
"transferred_classes": [
{
"from": "CLASS_NAME",
"from_script": "CURRENT_SCRIPT_NAME",
"to_script": "DESTINATION_SCRIPT_NAME"
}
]
}
Display generated migration for review:
Generated Migration:
====================
{
"tag": "v3",
"new_sqlite_classes": ["MyNewDO"]
}
This will be added to wrangler.jsonc migrations array.
Action Summary:
- Migration tag: v3
- Type: New class (SQL storage)
- Class: MyNewDO
- Backup: wrangler.jsonc.bak
Next steps after applying:
1. Ensure class exported: export class MyNewDO extends DurableObject { ... }
2. Add binding to wrangler.jsonc
3. Deploy: wrangler deploy
Apply this migration? [y/N]
Wait for user confirmation before proceeding.
Create backup of wrangler.jsonc before making changes:
cp wrangler.jsonc wrangler.jsonc.bak
Display backup location:
✅ Created backup: wrangler.jsonc.bak
Rollback command (if needed):
cp wrangler.jsonc.bak wrangler.jsonc
Apply migration to configuration file:
# Strip comments and parse JSON
grep -v '^\s*//' wrangler.jsonc | jq '.'
Use jq to append migration:
jq --argjson migration '{
"tag": "v3",
"new_sqlite_classes": ["MyNewDO"]
}' '.migrations += [$migration]' wrangler.jsonc > wrangler.jsonc.tmp
mv wrangler.jsonc.tmp wrangler.jsonc
Read updated config and verify migration was added:
jq '.migrations' wrangler.jsonc
Display:
✅ Migration added to wrangler.jsonc
Updated migrations array:
[
{ "tag": "v1", "new_sqlite_classes": ["MyDurableObject"] },
{ "tag": "v2", "new_sqlite_classes": ["ChatRoom"] },
{ "tag": "v3", "new_sqlite_classes": ["MyNewDO"] }
]
Run post-update validation:
jq '.' wrangler.jsonc > /dev/null
If validation fails:
❌ ERROR: Invalid JSON syntax after update
Rolling back to backup...
cp wrangler.jsonc.bak wrangler.jsonc
Please report this issue with your configuration.
Run validation script:
./scripts/validate-do-config.sh
Check for:
Display action-specific next steps:
✅ Migration Created Successfully!
Next Steps:
===========
1. Ensure class is exported in your Worker:
// src/index.ts or src/MyNewDO.ts
import { DurableObject } from "cloudflare:workers";
export class MyNewDO extends DurableObject {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
this.ctx.blockConcurrencyWhile(async () => {
// Initialize SQL schema
await this.ctx.storage.sql.exec(`
CREATE TABLE IF NOT EXISTS my_table (
id INTEGER PRIMARY KEY,
data TEXT NOT NULL
)
`);
});
}
}
2. Add binding to wrangler.jsonc:
"durable_objects": {
"bindings": [
{
"name": "MY_NEW_DO",
"class_name": "MyNewDO"
}
]
}
3. Update TypeScript Env interface:
interface Env {
MY_NEW_DO: DurableObjectNamespace<MyNewDO>;
}
4. Deploy migration:
wrangler deploy
5. Test DO creation:
curl https://your-worker.workers.dev?id=test
Documentation:
- Load templates/ for code examples
- Load references/migrations-guide.md for migration patterns
- Run /do-debug if deployment issues occur
✅ Rename Migration Created Successfully!
IMPORTANT: Code changes required before deploying!
Next Steps:
===========
1. Rename class in your code:
// OLD:
export class OldClassName extends DurableObject { ... }
// NEW:
export class NewClassName extends DurableObject { ... }
2. Update binding in wrangler.jsonc:
"durable_objects": {
"bindings": [
{
"name": "BINDING_NAME",
"class_name": "NewClassName" // ← Update this
}
]
}
3. Update TypeScript Env interface:
interface Env {
BINDING_NAME: DurableObjectNamespace<NewClassName>; // ← Update this
}
4. Deploy migration:
wrangler deploy
Note: Existing DO instances will continue to work.
The rename affects how new instances are created.
Documentation:
- Load references/migrations-guide.md for rename patterns
⚠️ Delete Migration Created
CRITICAL: This will PERMANENTLY DELETE all DO instances!
Before Deploying:
=================
1. Backup data if needed:
- Export important data from DO instances
- Archive to R2 or external storage
2. Remove class from code:
- Delete class definition
- Remove from exports
3. Remove binding from wrangler.jsonc:
- Delete binding entry
- Remove from Env interface
4. Deploy migration:
wrangler deploy
After Deployment:
=================
All DO instances and data will be permanently deleted.
This action CANNOT be undone!
Rollback (before deploying):
cp wrangler.jsonc.bak wrangler.jsonc
✅ Transfer Migration Created Successfully!
Next Steps:
===========
1. Ensure class exists in destination script:
// In destination script (DEST_SCRIPT_NAME)
export class TransferredClass extends DurableObject { ... }
2. Add binding to destination script's wrangler.jsonc:
"durable_objects": {
"bindings": [
{
"name": "TRANSFERRED",
"class_name": "TransferredClass",
"script_name": "DEST_SCRIPT_NAME"
}
]
}
3. Deploy BOTH scripts in order:
# Deploy destination script first
cd ../dest-script/
wrangler deploy
# Then deploy source script with migration
cd ../source-script/
wrangler deploy
4. Update references in source script:
- Change binding to point to destination script
- Or remove binding if no longer needed
Documentation:
- Load references/migrations-guide.md for transfer patterns
Handle common migration errors:
❌ ERROR: wrangler.jsonc contains invalid JSON
Location: Line 15, Column 23
Issue: Trailing comma in migrations array
Fix manually or restore backup:
cp wrangler.jsonc.bak wrangler.jsonc
❌ ERROR: Migration tag 'v3' already exists
Existing migration:
{ "tag": "v3", "new_sqlite_classes": ["OtherClass"] }
Solutions:
1. Use next sequential tag: v4
2. Choose different tag name
3. Cancel migration
❌ ERROR: Class 'MyNewDO' not exported in Worker code
Searched in:
- src/index.ts
- src/MyNewDO.ts
- src/durable-objects/MyNewDO.ts
Solutions:
1. Create class first: /do-setup
2. Export existing class: export class MyNewDO { ... }
3. Continue anyway (migration will fail on deploy)
After migration, recommend:
./scripts/validate-do-config.shwrangler deploy/do-setup (if enabled)/do-debug for deployment issuesreferences/migrations-guide.mdMigration is successful when: