Skip to content
Development
Skill

/skill-migrate

AL version migration for Business Central. Use when upgrading extensions between BC versions, handling breaking changes, or implementing rollback strategies.

BOOST
From plugin
aldc-al-development-collection
11237 skills28 agents11 commands4 MCP
Install
$ npx -y skills add javiarmesto/ALDC-AL-Development-Collection --skill skill-migrate --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/skill-migrate

Context preview

The summary Claude sees to decide when to auto-load this skill.

AL version migration for Business Central. Use when upgrading extensions between BC versions, handling breaking changes, or implementing rollback strategies.

SKILL.md

skill-migrate.SKILL.md
name: skill-migrate
description: "AL version migration for Business Central. Use when upgrading extensions between BC versions, handling breaking changes, or implementing rollback strategies."

Skill: AL Project Migration

Purpose

Plan and execute BC platform version upgrades: app.json configuration, breaking-change remediation, deprecated API replacement, event signature updates, upgrade codeunits for data migration, rollback strategy, and manifest regeneration.

When to Load

This skill should be loaded when:

  • Upgrading an AL extension to a newer BC platform version (e.g., BC 23.x → 24.x)
  • Fixing compilation errors after updating the runtime or platform property
  • Replacing deprecated AL patterns (C/AL legacy, obsolete APIs)
  • Updating event subscriber signatures after base-app changes
  • Writing upgrade codeunits for schema changes or data migration
  • Generating a full deployment package after migration

Core Patterns

For BC29 / AL18, first read [AL18 capability checks](references/al18-capabilities.md) when selecting new manifest, public-resource, isolation, testing or translation features. Apply only the sections needed by the requirement; distinguish announced capabilities from locally verified declarations. Keep BC28 configuration unchanged unless an upgrade is part of the approved task.

Pattern 1: App.json Platform Update

Update the three version-sensitive properties in `app.json`:

{
  "platform": "25.0.0.0",
  "runtime": "14.0",
  "application": "25.0.0.0",
  "dependencies": [
    {
      "id": "63ca2fa4-4f03-4f2b-a480-172fef340d3f",
      "name": "System Application",
      "publisher": "Microsoft",
      "version": "25.0.0.0"
    }
  ],
  "features": ["TranslationFile", "GenerateCaptions", "NoImplicitWith"]
}

**Rules:**

  • `platform` — target BC platform version (major.minor.0.0)
  • `runtime` — AL runtime version matching the target (see [runtime matrix](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-choosing-runtime))
  • `application` — must match or be compatible with target platform
  • Resolve each dependency by identity, minimum version, target runtime and required APIs; do not require every library version to numerically match the application version.
  • Add new `features` flags required by the target runtime (e.g., `NoImplicitWith` from runtime 11.0+)

Pattern 2: Deprecated Code Replacement

Replace legacy patterns with modern equivalents:

// ❌ Deprecated — C/AL style
Record.FIND('-');
Record.FINDSET(TRUE, TRUE);
IF Record.FINDFIRST THEN;
Record.INIT;
Record.INSERT;

// ✅ Modern — AL patterns
Record.FindSet();
Record.FindSet(true, true);
if Record.FindFirst() then;
Record.Init();
Record.Insert(true);
// ❌ Deprecated — WITH statement (removed in NoImplicitWith)
with SalesHeader do begin
    "Document Type" := "Document Type"::Order;
    "Sell-to Customer No." := CustomerNo;
    Insert(true);
end;

// ✅ Modern — explicit record reference
SalesHeader."Document Type" := SalesHeader."Document Type"::Order;
SalesHeader."Sell-to Customer No." := CustomerNo;
SalesHeader.Insert(true);
// ❌ Deprecated — TextConst (runtime < 6.0)
CustomerNotFoundErr@1000 : TextConst 'ENU=Customer %1 not found.';

// ✅ Modern — Label
var
    CustomerNotFoundErr: Label 'Customer %1 not found.';

Pattern 3: Event Signature Migration

When base-app events add or change parameters between versions:

// BC 23.x subscriber — 3 parameters
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post",
                 OnBeforePostSalesDoc, '', false, false)]
local procedure OnBeforePost(
    var SalesHeader: Record "Sales Header";
    CommitIsSuppressed: Boolean;
    var IsHandled: Boolean)
begin
    // ...
end;

// BC 24.x — same event now has 4 parameters (new PreviewMode added)
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post",
                 OnBeforePostSalesDoc, '', false, false)]
local procedure OnBeforePost(
    var SalesHeader: Record "Sales Header";
    CommitIsSuppressed: Boolean;
    PreviewMode: Boolean;
    var IsHandled: Boolean)
begin
    // ...
end;

**Migration steps:** 1. Build with `al_build` — signature mismatches produce `AL0482` errors 2. Use `al_get_object_definition` to inspect the new publisher signature 3. Update parameter list to match exactly (name, type, order) 4. Re-verify with `al_build`

Pattern 4: Obsolete Object Handling

Handle objects marked `ObsoleteState = Removed` in the target version:

// Step 1: Find usage of removed objects
// al_search_objects — search for the obsolete table/page/codeunit

// Step 2: Replace with the designated successor
// Before (removed in BC 24):
// Codeunit 80 "Sales-Post (Yes/No)" — ObsoleteState = Removed
// After:
Codeunit.Run(Codeunit::"Sales-Post", SalesHeader);

// Step 3: Check ObsoleteReason for migration guidance
// ObsoleteReason typically says: "Use codeunit X instead"

**Process:** 1. Compile → collect all `AL0503` (removed) and `AL0432` (pending) warnings 2. For `Removed` — must fix before compilation succeeds 3. For `Pending` — fix proactively to avoid future breaks 4. Check release notes for each removed object's replacement

Pattern 5: Upgrade Codeunit (Data Migration)

Use upgrade codeunits to transform data when schema changes between versions:

codeunit 50100 "Contoso Data Upgrade"
{
    Subtype = Upgrade;

    trigger OnUpgradePerCompany()
    var
        Module: Info;
    begin
        Module.DataVersion(1);      // check data version tracking
        MigrateCustomerLoyaltyData();
        SplitAddressFields();
    end;

    trigger OnValidateUpgradePerCompany()
    begin
        // Pre-upgrade validation — runs before OnUpgradePerCompany
        VerifyDataIntegrity();
    end;

    local procedure MigrateCustomerLoyaltyData()
    var
        Customer: Record Customer;
        ContosoLoyalty: Record "Contoso Loyalty Entry";
        UpgradeTag: Codeunit "Upgr
Read more
Ships withaldc-al-development-collection

Skills-based, spec-driven, TDD-orchestrated development framework for Microsoft Dynamics 365 Business Central. Engineering systems, visibly reasoned.

Get the whole plugin