Skip to content

fix(win32): wrap toast and sound scripts in try/catch for headless sessions#2222

Open
laciferin2024 wants to merge 2 commits intocode-yeongyu:devfrom
ideo-org:fix/windows-toast-ssh-headless
Open

fix(win32): wrap toast and sound scripts in try/catch for headless sessions#2222
laciferin2024 wants to merge 2 commits intocode-yeongyu:devfrom
ideo-org:fix/windows-toast-ssh-headless

Conversation

@laciferin2024
Copy link

@laciferin2024 laciferin2024 commented Mar 1, 2026

On SSH or headless Windows, the WinRT APIs for toast notifications aren't available, so CreateToastNotifier returns null and calling .Show() crashes. The JS catch handler prevents the whole thing from exploding, but PowerShell stderr still leaks through. Wrapped the generated toast script in try/catch at the PowerShell level to suppress that noise. Same fix for the sound playback command since it has the same issue.


Summary by cubic

Suppress stderr in headless/SSH Windows sessions by wrapping Windows toast and sound PowerShell commands in try/catch and forcing New-Object to throw with -ErrorAction Stop. Keeps notifications from spamming errors when WinRT isn’t available.

  • Bug Fixes
    • Wrap Windows toast script in PowerShell try/catch to swallow WinRT failures.
    • Wrap SoundPlayer command in try/catch and add -ErrorAction Stop to catch non-terminating errors.
    • Add tests for try/catch wrapping, single-line semicolon output, and proper escaping.

Written for commit c8e0192. Summary will update on new commits.

…ssions

When running OpenCode over SSH or in other headless Windows environments,
the WinRT notification APIs are unavailable. The PowerShell call to
CreateToastNotifier throws "The notification platform is unavailable."
which leaks to stderr even though the JS-level .catch() prevents a crash.

Wrap the generated PowerShell toast script in try/catch so the error is
swallowed at the PowerShell level, keeping stderr clean on headless sessions.
Same fix applied to the SoundPlayer command in playSessionNotificationSound.
@github-actions
Copy link
Contributor

github-actions bot commented Mar 1, 2026

All contributors have signed the CLA. Thank you! ✅
Posted by the CLA Assistant Lite bot.

Copy link

@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 3 files

Confidence score: 4/5

  • Potential error handling gap: in src/hooks/session-notification-sender.ts, PowerShell try/catch won’t catch non-terminating New-Object errors, so failures could slip past without being handled as intended.
  • Overall risk seems moderate since it’s a specific error-path behavior rather than a core logic change, so this is likely safe to merge with awareness.
  • Pay close attention to src/hooks/session-notification-sender.ts - ensure non-terminating New-Object errors are handled or converted to terminating errors.
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="src/hooks/session-notification-sender.ts">

<violation number="1" location="src/hooks/session-notification-sender.ts:98">
P2: PowerShell `try/catch` won't catch non-terminating errors from `New-Object`

The `New-Object` cmdlet emits non-terminating errors by default when the type cannot be found. PowerShell `try/catch` blocks only catch terminating errors, so non-terminating errors will bypass the catch block and leak to stderr. This defeats the PR's stated goal of suppressing stderr noise on headless Windows environments.

Add `-ErrorAction Stop` to convert non-terminating errors to terminating errors:
```powershell
try { (New-Object -ErrorAction Stop Media.SoundPlayer '${escaped}').PlaySync() } catch { }
```</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

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

@laciferin2024
Copy link
Author

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Mar 1, 2026
@laciferin2024
Copy link
Author

Good catch — added -ErrorAction Stop so non-terminating errors from New-Object get converted to terminating ones and the catch block actually fires.

@laciferin2024 laciferin2024 force-pushed the fix/windows-toast-ssh-headless branch from 267018b to c8e0192 Compare March 1, 2026 04:00
@code-yeongyu
Copy link
Owner

[sisyphus-bot]

Thanks for this fix! The PR looks solid — wrapping WinRT calls in try/catch for headless Windows sessions is a clean solution.

Assessment Summary:

  • ✅ CI checks passing (CLA, GitGuardian)
  • ✅ Mergeable state clean
  • ✅ Targeted bugfix with tests
  • ⚠️ Awaiting review approval

What the PR does:

  • Wraps PowerShell script in try/catch
  • Wraps command in try/catch with
  • Adds comprehensive tests verifying the try/catch wrapper behavior

This addresses the issue where WinRT APIs fail on SSH/headless Windows and leak stderr despite JS-level catch handlers.

Next step: A maintainer review and approval is needed before this can be merged.

cc: code-yeongyu for review

dorgonman pushed a commit to kanohorizonia/oh-my-opencode that referenced this pull request Mar 2, 2026
@laciferin2024
Copy link
Author

YaY, happy to report the bug with a fix. I have been using my build for the past 2 days and i can attest that bug is resolved on windows server 2020.

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.

2 participants