migrating-motoko-enhanced

Migrate Motoko canister state across upgrades using chained migration modules.

Updated Apr 3, 2026
One-click install
npx skills add https://github.com/phukrit7171/Relationship-Smart-Contract-ICP --skill migrating-motoko-enhanced-phukrit7171
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: migrating-motoko-enhanced
Source: https://github.com/phukrit7171/Relationship-Smart-Contract-ICP/tree/main/.agents/skills/migrating-motoko-enhanced
Command: npx skills add https://github.com/phukrit7171/Relationship-Smart-Contract-ICP --skill migrating-motoko-enhanced-phukrit7171

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Upgrading a Motoko canister often requires changing persistent actor state — adding fields, renaming them, or changing their types — and doing this by hand with stable variables and preupgrade/postupgrade hooks is error-prone. This Skill manages state evolution as a verified chain of migration modules that the compiler checks for consistency. ## Core Features & Use Cases - Chained migration modules: Each logical state change lives in its own timestamped file under a migrations/ directory, and the compiler verifies the whole chain composes correctly. - Field transformations: Add, rename, drop, retype, or restructure actor fields, including mapping over collections and converting Bool fields to variants. - Safe upgrade semantics: On upgrade only unapplied migrations run, fast-forwarding across skipped deployments works, and a trapping migration aborts the upgrade leaving the old version intact. - Use Case: You need to change a completed : Bool field to a status variant across thousands of stored tasks. Write one migration module that maps over the collection, run mops check --fix to verify the chain, and deploy with confidence. ## Quick Start Ask the AI to set up an enhanced migration chain for your Motoko actor by creating a migrations directory with an Init module and configuring mops.toml.

Frequently Asked Questions about migrating-motoko-enhanced

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I migrate Motoko canister state across upgrades?

Create a migrations directory next to your actor and add timestamped modules, each exporting a public func migration that takes the old state record and returns the new one. Configure [canisters.<name>.migrations] in mops.toml and mops injects --enhanced-migration automatically.

How to rename or change a field type in a Motoko actor?

Write a migration module whose input record contains the old field and whose output record contains the new field, for example taking { header : Text } and returning { title : Text }. Fields present in both input and output are transformed, output-only fields are added, and input-only fields are removed.

What is the difference between enhanced migration and inline migration in Motoko?

Enhanced migration uses a migrations directory of chained modules verified by the compiler, suited for multi-step state evolution across deployments. Inline migration with (with migration = ...) handles a single one-shot change and cannot be combined with --enhanced-migration.

Can I use stable variables or preupgrade hooks with enhanced migration?

No. Enhanced migration forbids the stable keyword, preupgrade/postupgrade hooks, and inline migration expressions. Actor variables are declared without initializers because their values come from the migration chain, and the actor body must be static.

What happens if a Motoko migration traps during an upgrade?

If any migration in the chain traps, the upgrade is aborted and the canister stays on the old version with its existing state. On a fresh deploy all migrations run in order, while upgrades run only the migrations not yet applied.

Why does mops error when I add --enhanced-migration to canister args?

When [canisters.<name>.migrations] is configured in mops.toml, mops automatically injects --enhanced-migration into check, build, and check-stable. Adding the flag manually to the canister args causes a duplicate-flag error, so remove it from args.