Skip to content

Fix opaque "Process exited with code 1" in VS Code workspace view#9136

Open
vhvb1989 wants to merge 3 commits into
mainfrom
fix/vscode-show-error-surfacing
Open

Fix opaque "Process exited with code 1" in VS Code workspace view#9136
vhvb1989 wants to merge 3 commits into
mainfrom
fix/vscode-show-error-surfacing

Conversation

@vhvb1989

@vhvb1989 vhvb1989 commented Jul 14, 2026

Copy link
Copy Markdown
Member

Warning

Blocked by #9140 — the azure-dev - vscode ADO pipeline currently fails for all ext/vscode PRs due to npm ci --no-optional dropping esbuild's platform binary (unrelated to this change). GitHub build-test is green on all 3 OSes for this commit.

Fixes #9130 (and its duplicate #9131).

Problem

Customers received an opaque error notification with a Report Issue button:

Action: azure-dev.views.workspace.application.resolve
Error type: 1
Error Message: Process exited with code 1
Call Stack: ChildProcess.<anonymous> extension.js:2:535569

Root cause

The Azure Resources workspace tree view resolves each application node by running
azd show --no-prompt --cwd <dir> --output json via execAsync
(AzureDevCliApplication.getResultsWorkspaceAzureDevShowProvider.getShowResults).

  1. When azd show exits non-zero, spawnStreamAsync rejects from inside a ChildProcess
    exit handler with a generic Process exited with code 1 message (hence the
    ChildProcess.<anonymous> call stack) — before execAsync ever reads the accumulated
    stderr. So the real azd error (on stderr) is silently discarded, and the existing
    azure.yaml error classification in getShowResults can never match.
  2. getResults did not set suppressDisplay, so this background tree resolution surfaced a
    modal error with a Report Issue prompt. Routine states (not logged in, no environment yet,
    invalid azure.yaml) therefore looked like extension bugs and got auto-reported (Process exited with code 1 #9130, Process exited with code 1 #9131).

Fix

  • execAsync.ts — on a non-zero exit, append the child process's stderr to the thrown
    error's message. AccumulatorStream.getString() awaits the stream close event, so stderr is
    fully flushed (no race). This surfaces the real reason and makes the existing classification in
    AzureDevShowProvider effective.
  • AzureDevCliApplication.getResults — set errorHandling.suppressDisplay = true for this
    passive tree resolution so expected/environmental failures no longer pop a Report Issue dialog.
    Telemetry still records the failure for real triage, and azure.yaml problems continue to be
    reported via the Problems panel.
  • Tests — added execAsync unit tests (success, stderr-on-failure, empty-stderr failure).

Validation

  • npm run lint
  • npx tsc --noEmit
  • npx cspell "src/**/*.ts" --config .vscode/cspell.yaml ✓ (0 issues)
  • npm run build (esbuild + tsc) ✓
  • npm test (vscode-test) could not run in this environment (requires a display/Xvfb, which is
    unavailable). The new tests use the current Node.js executable to exercise the real
    spawnStreamAsync path cross-platform.

@vhvb1989
vhvb1989 force-pushed the fix/vscode-show-error-surfacing branch from 7adc968 to b19aa8e Compare July 14, 2026 16:36
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
21 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@vhvb1989

Copy link
Copy Markdown
Member Author

/azp run azure-dev - vscode

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@vhvb1989

Copy link
Copy Markdown
Member Author

🚧 Blocked by #9140. The remaining red check (azure-dev - vscode on ADO) is a pre-existing pipeline/tooling failure (esbuild platform binary dropped by npm ci --no-optional), not caused by this PR. GitHub build-test (same ci-test.ps1) passes on ubuntu/macos/windows for this commit. This PR can merge once #9140 is resolved.

vhvb1989 and others added 2 commits July 20, 2026 18:50
The Azure Resources workspace tree resolves each application node by
running `azd show --no-prompt --output json` via execAsync. When azd
exits non-zero, spawnStreamAsync rejects from a ChildProcess handler
with a generic "Process exited with code 1" message *before* the caller
reads stderr, so the real azd error is discarded. The failure is then
reported as a modal error with a "Report Issue" button, prompting users
to file bugs (e.g. #9130, #9131) for routine states like not being
logged in or having no environment yet.

- execAsync: on non-zero exit, append the child process's stderr to the
  error message so callers can classify and report the real failure
  instead of an opaque exit code. This also makes the existing
  azure.yaml error classification in AzureDevShowProvider effective.
- AzureDevCliApplication.getResults: suppress the error display for this
  background tree resolution so expected/environmental failures no
  longer surface a Report Issue popup. Telemetry still records them.
- Add execAsync unit tests covering success, stderr-on-failure, and
  empty-stderr failure paths.

Fixes #9130

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8907c2b4-8adc-4280-8f11-af43d905644f
The previous execAsync test spawned a real `node -e` subprocess, which
failed on Windows CI: NoShell stripped the inner double quotes from the
inline script (`process.stdout.write(out)` -> ReferenceError). Relying on
a real process / process.execPath inside the extension host is fragile
and platform-dependent.

Add an optional injectable spawn function to execAsync (defaulting to the
real spawnStreamAsync) and rewrite the tests to inject a fake that writes
to the accumulator pipes and resolves/rejects. This exercises the real
stderr-appending logic deterministically with no subprocess, so it passes
identically on Linux, macOS, and Windows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8907c2b4-8adc-4280-8f11-af43d905644f
@vhvb1989
vhvb1989 force-pushed the fix/vscode-show-error-surfacing branch from 82e3535 to 304a3cd Compare July 20, 2026 18:51
@vhvb1989
vhvb1989 marked this pull request as ready for review July 20, 2026 18:52
Copilot AI review requested due to automatic review settings July 20, 2026 18:52
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
21 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@github-actions

Copy link
Copy Markdown

📋 Prioritization Note

Thanks for the contribution! The linked issue isn't in the current milestone yet.
Thank you for logging this issue; our team is reviewing it. If you need urgent prioritization, tag @RickWinter and @kristenwomack to let us know.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves VS Code workspace-view error handling for failed azd show calls.

Changes:

  • Suppresses background tree-resolution error dialogs.
  • Includes stderr in process-exit errors.
  • Adds unit tests and release notes.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
AzureDevCliApplication.ts Suppresses passive resolution dialogs.
execAsync.ts Appends stderr to exit errors.
execAsync.test.ts Tests process output and failures.
CHANGELOG.md Documents the fix.

Comment thread ext/vscode/src/utils/execAsync.ts
Comment thread ext/vscode/src/test/suite/unit/execAsync.test.ts

@jongio jongio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One issue on the error-surfacing change, the rest looks fine.

The new catch block in execAsync can hang for any rejection that isn't a non-zero process exit (details inline). I confirmed it against @microsoft/vscode-processutils 0.2.1: with this change an ENOENT command (azd not on PATH) never settles, where the old await spawnStreamAsync(...) rejected right away. Gating the stderr read on isChildProcessError keeps the fix for the code-1 case while letting pre-spawn and spawn-error failures rethrow.

The suppressDisplay change and CHANGELOG entry look good.

Comment thread ext/vscode/src/utils/execAsync.ts
Comment thread ext/vscode/src/test/suite/unit/execAsync.test.ts
- execAsync: only append stderr for ChildProcessError (non-zero exit);
  rethrow pre-spawn failures (cancelled token, Windows exe-resolution)
  immediately so an un-ended stderr pipe can't hang execAsync.
- Tests: use ChildProcessError for exit cases; add a pre-spawn regression
  test that guards against the hang; make the exit-error test close stderr
  AFTER the spawn promise rejects to reproduce the real ordering and prove
  execAsync waits for stderr before appending it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bfac0afb-0a7c-4406-93f8-ee4506b494e6
Copilot AI review requested due to automatic review settings July 21, 2026 18:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

// environment yet, invalid azure.yaml) rather than an extension bug, so don't surface a
// modal error with a "Report Issue" button. The failure is still captured in telemetry,
// and azure.yaml problems are reported independently via the Problems panel.
actionContext.errorHandling.suppressDisplay = true;

suite('execAsync Tests', () => {
test('Returns stdout and stderr on success', async () => {
const { stdout, stderr } = await execAsync('cmd', [], undefined, fakeSpawn('out', 'err'));

@jongio jongio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The isChildProcessError gate resolves the pre-spawn hang I flagged, and the new pre-spawn regression test (guarded by the 1s timeout) locks it in. Verified the exit-error test now closes stderr after the rejection, so it proves execAsync waits for the flushed stderr before appending it.

@azure-sdk-automation

Copy link
Copy Markdown
Contributor

VSCode Extension Installation Instructions

  1. Download the extension at https://azuresdkartifacts.z5.web.core.windows.net/azd/vscode/pr/9136/azure-dev-0.11.0-alpha.1.vsix
  2. Extract the extension from the compressed file
  3. In vscode
    a. Open "Extensions" (Ctrl+Shift+X)
    b. Click the ...\ menu at top of Extensions sidebar
    c. Click "Install from VSIX"
    d. Select location of downloaded file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Process exited with code 1

4 participants