Skip to content

fix: fall back to cmd.exe when PowerShell is unavailable on Windows#12034

Open
octo-patch wants to merge 2 commits intocontinuedev:mainfrom
octo-patch:fix/issue-11960-windows-cmd-powershell-fallback
Open

fix: fall back to cmd.exe when PowerShell is unavailable on Windows#12034
octo-patch wants to merge 2 commits intocontinuedev:mainfrom
octo-patch:fix/issue-11960-windows-cmd-powershell-fallback

Conversation

@octo-patch
Copy link
Copy Markdown
Contributor

@octo-patch octo-patch commented Apr 4, 2026

Fixes #11960

Problem

On Windows environments where PowerShell is blocked by corporate security policy (e.g., AppLocker), run_terminal_command fails immediately with:

run_terminal_command failed with the message: spawn UNKNOWN

This happens because getShellCommand() always returns powershell.exe on Windows, even when PowerShell cannot be executed.

Solution

Introduce a module-level flag _powershellUnavailable that is set to true when a PowerShell spawn fails with an UNKNOWN or ENOENT error code. Once set, getShellCommand() falls back to cmd.exe (via COMSPEC) for all subsequent invocations in the session.

This approach:

  • Preserves existing PowerShell behavior for users where it works
  • Automatically recovers for restricted environments on the next command invocation
  • Requires no configuration changes from the user

Testing

  • On non-Windows: no behavior change (existing tests still pass)
  • On Windows with PowerShell available: no behavior change
  • On Windows with PowerShell blocked: first call fails with the existing error; subsequent calls use cmd.exe and succeed

Summary by cubic

Automatically fall back to cmd.exe when PowerShell can't start on Windows, so run_terminal_command keeps working in restricted environments (fixes #11960). Also reduces a noisy error log in the document history tracker (addresses #11919).

  • Bug Fixes
    • Windows: detect PowerShell spawn errors (UNKNOWN/ENOENT), set a session flag, and route subsequent commands to cmd.exe via COMSPEC; no change for users where PowerShell works.
    • DocumentHistoryTracker: downgrade console.error to console.debug when a document isn’t in the tracker, avoiding noisy logs while still adding the document.

Written for commit 26c16ad. Summary will update on new commits.

…er.push()

When onDidChangeVisibleTextEditors fires, deleteChain() calls push() on the
DocumentHistoryTracker for the previous request filepath. Because
onDidOpenTextDocument is currently disabled (pending PR continuedev#8364 merge),
documents are never pre-added via addDocument(), so push() always takes the
fallback path and logs a console.error on every editor switch.

The fallback in push() already handles this gracefully by calling
addDocument(), making the error log misleading noise. Downgrade it to
console.debug so it remains accessible for debugging without polluting the
Extension Host output.

Fixes continuedev#11919
continuedev#11960)

On Windows environments where PowerShell is blocked by corporate security
policy (e.g., AppLocker), run_terminal_command would fail with 'spawn UNKNOWN'.

This change introduces a module-level flag that is set when PowerShell fails
to spawn (UNKNOWN or ENOENT error code). Once set, getShellCommand() falls
back to cmd.exe via COMSPEC for all subsequent calls in the session, allowing
the tool to work without further user intervention after the first failure.
@octo-patch octo-patch requested a review from a team as a code owner April 4, 2026 05:06
@octo-patch octo-patch requested review from sestinj and removed request for a team April 4, 2026 05:06
@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Apr 4, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="core/tools/implementations/runTerminalCommand.ts">

<violation number="1" location="core/tools/implementations/runTerminalCommand.ts:381">
P2: Sticky PowerShell fallback is triggered by broad error codes (`UNKNOWN`/`ENOENT`) instead of a PowerShell-specific spawn failure, so one misclassified error can permanently switch future Windows commands to `cmd.exe`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

// mark it unavailable so future calls fall back to cmd.exe automatically.
if (
process.platform === "win32" &&
(error.code === "UNKNOWN" || error.code === "ENOENT")
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 4, 2026

Choose a reason for hiding this comment

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

P2: Sticky PowerShell fallback is triggered by broad error codes (UNKNOWN/ENOENT) instead of a PowerShell-specific spawn failure, so one misclassified error can permanently switch future Windows commands to cmd.exe.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At core/tools/implementations/runTerminalCommand.ts, line 381:

<comment>Sticky PowerShell fallback is triggered by broad error codes (`UNKNOWN`/`ENOENT`) instead of a PowerShell-specific spawn failure, so one misclassified error can permanently switch future Windows commands to `cmd.exe`.</comment>

<file context>
@@ -360,6 +374,15 @@ export const runTerminalCommandImpl: ToolImpl = async (args, extras) => {
+            // mark it unavailable so future calls fall back to cmd.exe automatically.
+            if (
+              process.platform === "win32" &&
+              (error.code === "UNKNOWN" || error.code === "ENOENT")
+            ) {
+              _powershellUnavailable = true;
</file context>
Fix with Cubic

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

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

run_terminal_command fails with "spawn UNKNOWN" on Windows CMD environment

1 participant