microsoft / microsoft/AL

`altool workspace compile` crashes with `IOException: The handle is invalid` when stdout is redirected (v17.0.2273547)

Open Beginner friendly
#8,226 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

accepted al-tools bug
Dominant language
PowerShell
Stars
881
Forks
285
Avg merge
3d 36m
Merged PRs (30d)
1

Description

Summary

altool workspace compile throws an unhandled System.IO.IOException: The handle is invalid during CompilationStatus.UpdateProgress() when invoked from a non-interactive shell (pipes, CI runners, redirected output). The compilation never actually runs ÔÇö the crash happens almost immediately after the "Starting compilation" banner.

Environment

  • AL Language extension: 17.0.2273547 (published 2026-04-01)
  • OS: Windows 11 Pro for Workstations 10.0.26200
  • .NET 8.0.25 runtime
  • Shell: Git Bash (non-interactive / redirected stdout)

Reproduction

altool.exe workspace compile "path/to/workspace.code-workspace" 2>&1 | tail -80

Any redirection of stdout triggers it ÔÇö | tee, > file.log, piping through head/tail, or running inside a CI runner that captures the child process's streams.

Running the same command directly in a Windows Terminal / cmd.exe window with no redirection works correctly.

Expected

When stdout is not a TTY, workspace compile should disable the interactive progress display and emit plain line-by-line status output (or at least guard the Console.WindowWidth call and fall back to a sensible default). Competing CLI tools (e.g. dotnet build, msbuild) degrade gracefully under redirection.

Actual

Starting compilation of 2 project(s) with 22 parallel task(s)...
Log directory: C:\Repos\...\logs

Unhandled exception. System.IO.IOException: The handle is invalid.
   at System.ConsolePal.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
   at System.ConsolePal.get_WindowWidth()
   at Microsoft.Dynamics.Nav.Tool.CompilationStatus.UpdateProgress() in X:\source\Prod\altool\Workspace\WorkspaceCompileCommand.cs:line 130
   at Microsoft.Dynamics.Nav.Tool.WorkspaceCompileCommand.<>c__DisplayClass17_0.<CompileGraphWithConcurrency>b__0(Object _) in X:\source\Prod\altool\Workspace\WorkspaceCompileCommand.cs:line 766
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.TimerQueueTimer.Fire(Boolean isThreadPool)
   at System.Threading.TimerQueue.FireNextTimers()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()

Process exits with a non-zero code and no logs/ output is written (the directory is created but remains empty), so CI pipelines lose both the build result and the diagnostic trail.

Suggested fix

Guard the Console.WindowWidth call in CompilationStatus.UpdateProgress(). The standard .NET idiom is:

int width;
try { width = Console.IsOutputRedirected ? 120 : Console.WindowWidth; }
catch (IOException) { width = 120; }

Or simpler: skip progress updates entirely when Console.IsOutputRedirected == true.

Impact

Blocks altool workspace compile from use in automation scenarios ÔÇö CI pipelines, Git hooks, scripted multi-project builds, and agentic tooling that captures subprocess output. Any wrapper that redirects the child's stdout hits this immediately.

As a workaround, direct alc.exe invocation per project works fine under redirection ÔÇö only the workspace-level orchestration is affected.

Internal work item: AB#631155

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with Workspace/WorkspaceCompileCommand.cs, especially CompilationStatus.UpdateProgress() around line 130, and reproduce using the redirected-output command in the issue. Confirm that workspace compilation no longer crashes under stdout redirection, produces status output or safely skips interactive progress, and preserves diagnostic logs.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
cli
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.