al_symbolsearch (AL MCP server) crashes with NullReferenceException on any scope=dependencies / scope=all query
Nobody has claimed this yet.
- Dominant language
- PowerShell
- Stars
- 881
- Forks
- 285
- Avg merge
- 3d 36m
- Merged PRs (30d)
- 1
Description
Describe the bug
The AL MCP server tool al_symbolsearch deterministically crashes for any query whose
scope includes dependency symbols (filters.scope = "dependencies", or the default
"all" whenever the result must include a dependency-side object). The MCP client only
receives the generic An error occurred invoking 'al_symbolsearch'; the server stderr
shows an unhandled System.NullReferenceException thrown while building symbol
descriptors for dependency keys.
scope=project works fine. The companion tool al_getpackagedependencies returns all
referenced packages correctly, so the symbols are loaded ΓÇö the failure is purely inside
al_symbolsearch's dependency descriptor-build path, while rendering a table Key.
This is not the same as #8227 (which is a session/caching issue after
al_addproject, has no stack trace, and is resolved by /mcp reload). The crash here is
a hard NullReferenceException that reproduces on a freshly started server with no
al_addproject/al_downloadsymbols in the session, and is not resolved by reload or
by re-downloading symbols.
Stack trace (captured from server stderr)
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.Dynamics.Nav.CodeAnalysis.Symbols.ReferenceKeySymbol.AppendFieldMembers(PooledNameObjectDictionary`1 fields, ContainerSymbol table) in X:\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\Symbols\Reference\ReferenceKeySymbol.cs:line 83
at Microsoft.Dynamics.Nav.CodeAnalysis.Symbols.ReferenceKeySymbol.GetLazyFields() in X:\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\Symbols\Reference\ReferenceKeySymbol.cs:line 60
at System.Lazy`1.CreateValue()
at Microsoft.Dynamics.Nav.CodeAnalysis.SymbolDisplayVisitor.VisitKey(KeySymbol symbol) in X:\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\SymbolDisplay\SymbolDisplayVisitor.cs:line 897
at Microsoft.Dynamics.Nav.CodeAnalysis.Workspaces.LanguageModelTools.SymbolSearch.SymbolSearchService.SymbolDescriptor.Create(Symbol symbol, Symbol containerSymbol, SymbolSearchScope scope, Boolean isTopLevel, CancellationToken cancellationToken) in X:\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis.Workspaces\LanguageModelTools\SymbolSearch\SymbolSearchService.cs:line 606
at Microsoft.Dynamics.Nav.CodeAnalysis.Workspaces.LanguageModelTools.SymbolSearch.SymbolSearchService.AppendMembers(Builder builder, ContainerSymbol container, Symbol rootContainer, SymbolSearchScope scope, CancellationToken cancellationToken) in ...SymbolSearchService.cs:line 202
at ...SymbolSearchService.BuildDescriptors(IEnumerable`1 topLevelSymbols, SymbolSearchScope scope, CancellationToken cancellationToken) in ...SymbolSearchService.cs:line 184
at ...SymbolSearchService.GetDependencyDescriptorsAsync(Compilation compilation, CancellationToken cancellationToken) in ...SymbolSearchService.cs:line 152
at ...SymbolSearchService.SearchAsync(ProjectId projectId, SymbolSearchParameters parameters, CancellationToken cancellationToken) in ...SymbolSearchService.cs:line 76
at Microsoft.Dynamics.BusinessCentral.ALMcp.Services.SymbolSearchToolService.SearchAsync(...) in ...almcp\Services\SymbolSearchToolService.cs:line 52
Likely root cause
GetDependencyDescriptorsAsync walks every top-level dependency symbol via
BuildDescriptors → AppendMembers, and for each KeySymbol calls
SymbolDescriptor.Create → SymbolDisplayVisitor.VisitKey, which forces
ReferenceKeySymbol.GetLazyFields() → AppendFieldMembers. For at least one key in the
Microsoft Base Application symbol set, a field reference resolves to null and
AppendFieldMembers (ReferenceKeySymbol.cs:83) dereferences it without a guard, throwing
NullReferenceException and aborting the entire dependency walk.
Because descriptors are built before the query / kinds / objectName / limit
filters are applied, no query narrowing avoids the bad key ΓÇö every dependency-scope call
fails the same way.
Suggested fix: null-guard in ReferenceKeySymbol.AppendFieldMembers (and/or
SymbolDisplayVisitor.VisitKey) so an unresolved key-field is skipped instead of
crashing; ideally also isolate per-symbol descriptor failures in BuildDescriptors so
one bad symbol can't abort the whole result set.
To Reproduce
- Any AL project whose
.alpackagescontains Microsoft Base Application 28.0
(28.0.46665.50632) + System Application 28.0 symbols. - Start the MCP server:
altool.exe launchmcpserver <project> --transport stdio --packagecachepath <.alpackages> - Invoke
al_symbolsearchwith a dependency-scoped query, e.g.:{ "name": "al_symbolsearch", "arguments": { "parameters": { "query": "Customer", "filters": { "scope": "dependencies", "kinds": ["Table"], "limit": 3 } } } }
Expected: matching dependency tables returned.
Actual: {"content":[{"type":"text","text":"An error occurred invoking 'al_symbolsearch'."}],"isError":true}; server stderr logs the NullReferenceException above.
What was ruled out
- Not a result-size/timeout issue. Tight
limitand specificquerycrash identically; the crash is in descriptor build, before filtering. (AnOperationCanceledExceptiononly appears if the client closes stdin mid-request ΓÇö that is a shutdown artifact, not the bug.) - Not query-narrowable.
objectName="Customer", memberKinds=["Field"], scope=dependenciescrashes the same way. - Not fixed by re-downloading symbols. Wiping
.alpackagesand re-runningal_downloadsymbols force=truereturned byte-identical Base Application28.0.46665.50632; the crash persists ΓÇö confirming the defect is in the symbol renderer, not the symbol data. - Not #8227. No
al_addprojectinvolved;/mcp reloaddoes not help; a stack trace is present.
Environment
- AL VS Code extension: ms-dynamics-smb.al-17.0.2273547
altoolversion: 17.0.34.45391+89ddc161d3e4421fa7ecef442abf29ca6e6ebfba- OS: Windows 11 Pro 26200
- Dependency symbols: Microsoft Base Application / System Application 28.0.46665.50632, System 28.0.50354, Application/Business Foundation 28.0.46665.48257
- Transport: stdio
Internal work item: AB#638487
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ReferenceKeySymbol.cs at AppendFieldMembers line 83, then trace GetLazyFields through SymbolDisplayVisitor.VisitKey and SymbolSearchService.SymbolDescriptor.Create. Reproduce with the dependency-scoped al_symbolsearch request against the specified Base and System Application symbols. Done means dependency searches return matching tables instead of an unhandled NullReferenceException, while unresolved key fields no longer abort descriptor construction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100