Skip to content

al_compile/al_build MCP tools return stale cached success after a cross-project breaking change #8325

Description

1. Describe the bug

The Copilot/agent tool al_compile (and al_build) returns a stale, cached compilation result that does not reflect the current state of source files on disk.

In a multi-root workspace with two AL projects (an "App" project and a "Test" project that depends on it), after registering both projects and running an initial successful build/compile, the tools stop re-validating cross-project symbol references on subsequent calls:

  • Renaming (or removing) a field in the App project that the Test project references does not surface as a compile error via al_compile/al_build, even after the App project itself is rebuilt and confirmed to compile cleanly with the new field name.
  • al_getdiagnostics for the same project also returns the old, now-incorrect diagnostic locations/messages instead of current ones.
  • A genuine command-line compile with alc.exe against the exact same files on disk correctly fails with AL0132 ("does not contain a definition for ...").
  • The stale result persists across repeated calls, across re-running al_addproject for the project, and even when the same tool is invoked from a separate/fresh session ΓÇö it is tied to the running MCP server process, not to any particular caller.
  • The only thing that resolved it was fully restarting the underlying MCP server process.

This makes al_compile/al_build unsafe to rely on for validating cross-project breaking changes ΓÇö they can report succeeded: true with zero diagnostics for code that genuinely does not compile.

Server setup: the al_compile/al_build tools are exposed by an MCP server registered in the user-level mcp.json (not project-local), launched via the al CLI ΓÇö installed as a .NET global tool ΓÇö with launchmcpserver --transport stdio:

"al-tool": {
    "type": "stdio",
    "command": "al",
    "args": ["launchmcpserver", "--transport", "stdio"]
}

This is a long-running stdio process shared across the whole VS Code session (and across subagent invocations) ΓÇö the staleness is tied to that one running process, not to any particular editor tab or caller.

2. To Reproduce

  1. Create a two-project AL workspace: App (defines a table extension field) and Test (depends on App, references that field).
// App/Source/MyTableExt.al
tableextension 50100 "MyTableExt" extends "Job Task"
{
    fields
    {
        field(50100; "MyCustomField"; Boolean)
        {
            Caption = 'My Custom Field';
            DataClassification = CustomerContent;
        }
    }
}
// Test/Source/MyTest.Codeunit.al
codeunit 50100 "MyTest"
{
    Subtype = Test;

    [Test]
    procedure "Field is accessible"()
    var
        JobTask: Record "Job Task";
    begin
        JobTask."MyCustomField" := true;
    end;
}
  1. Register both projects with the agent tooling (al_addproject for App, then for Test).
  2. Run al_build (or al_compile) for Test ΓÇö confirm it succeeds.
  3. Rename "MyCustomField" to "MyCustomField2" everywhere in the App project only (leave Test referencing the old name).
  4. Run al_build for App directly ΓÇö confirm it succeeds (App is internally consistent).
  5. Run al_compile (or al_build) for Test again, without restarting anything.
  6. Compare against a genuine command-line compile of Test with alc.exe using the same .alpackages/source.

3. Expected behavior

Step 6 should fail with AL0132:

'Record "Job Task"' does not contain a definition for 'MyCustomField'

matching what the command-line alc.exe compile in step 7 reports.

4. Actual behavior

Step 6 reports:

{ "succeeded": true, "diagnostics": [], "message": "" }

(or, for al_build, "succeeded": true" with a package generated and no errors), while the equivalent alc.exe run fails with 2 real AL0132 errors at the exact expected locations. This was reproduced consistently across multiple repeated attempts, after re-adding the project via al_addproject, and from a separate subagent session ΓÇö the stale result only cleared after the MCP server process itself was restarted.

5. Versions:

  • AL Language: 17.0.2273547 (compiler reported as 17.0.34)
  • Visual Studio Code: 1.134.0
  • Business Central: platform/application symbols observed at 28.4.53241.53873 (workspace app.json targets 27.0.0.0)
  • List of Visual Studio Code extensions that you have installed: AL Language extension
  • Operating System:
    • Windows
    • Linux
    • MacOS

Final Checklist

Please remember to do the following:

  • Search the issue repository to ensure you are reporting a new issue

  • Reproduce the issue after disabling all extensions except the AL Language extension

  • Simplify your code around the issue to better isolate the problem

Internal work item: AB#648679

Activity

  1. jacobsoee commented on Aug 27, 2026

    @jacobsoee

    This has been an annoyance for me aswell.
    Crossing fingers it will get solved.

  2. nnegrelli commented on Sep 8, 2026

    @nnegrelli

    I have a similar problem with the al mcp server: if I use al_compile and resolve all the errors, if I relaunch al_compile I always get the same errors, even if resolved and "succeeded" remains false.

  3. Arthurvdv commented on Sep 22, 2026

    @Arthurvdv

    Yep, I’m also running into this quite often. The agent’s quality goes downhill pretty quickly when the cache is stale. For now, I’ve added these instructions to circumvent the problem and that seems to be working 🤞

    ## MCP stale-cache recovery
    
    When you create or edit many `.al` files in a session the `al` MCP server may show stale diagnostics. Symptoms: `AL0185` "X is missing"
    errors for objects that exist on disk, cascading to every file that references them. `al_addproject` does not help -
    it short-circuits when the project is already loaded.
    
    `CompilationService.ReloadWorkspace()` exists and does a full tear-down + rebuild (disposes watchers, disposes the
    workspace, creates a fresh one, re-loads all projects from disk), but it is only called internally after
    `al_downloadsymbols` downloads >0 symbols - it is not exposed as a standalone MCP tool. When Microsoft ships a
    fix for #8325 (likely an `al_reloadworkspace` tool or automatic invalidation), this section can be removed.
    
    ### How to force a full reload
    
    Call `al_downloadsymbols` with `globalSourcesOnly: true` and `force: true`. This forces a re-download of Microsoft
    symbols (no authentication needed), and because the downloaded count is >0 it triggers `ReloadWorkspace()` — a
    complete cache wipe and project re-load. Run `analyze` again afterwards to get clean diagnostics.
    
    ### Triage when you suspect stale diagnostics
    
    1. Force-reload the workspace as described above.
    2. If phantom errors persist after the reload, they are real — look for error codes **other than** `AL0185` and
       `AL0118` (the cascade codes) first.
    3. Grep-based syntax scan on new `.al` files as a secondary check:
       - Orphaned `else`: `grep -rn "; *$" *.al | grep -B1 else` (semicolon before else)
       - `this.` in requestpage triggers: `this.` refers to RequestOptionsPage, not the report
       - Procedure call in `Enabled`/`Visible`: use a variable set in `OnAfterGetRecord` instead
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions