Skip to content

fix: fall back to Dart on native binary spawn errors; drop retired macOS x64 CI target - #55

Merged
charliewwdev merged 1 commit into
ai-dashboad:mainfrom
ihancock:fix/native-binary-spawn-error-fallback
Aug 21, 2026
Merged

charliewwdev merged 1 commit into
ai-dashboad:mainfrom
ihancock:fix/native-binary-spawn-error-fallback

Conversation

@ihancock

Copy link
Copy Markdown
Contributor

Summary

  • runNativeBinary() had no handler for spawn() launch failures. On macOS/Node 22, spawn() throws ENOEXEC synchronously for a non-executable cached binary; other failure modes (EACCES, wrong-arch) surface only via the async 'error' event. Neither path was covered, so a bad cached binary crashed the CLI instead of reaching the Dart fallback main() already implements for the "binary missing" case. Fixed by wrapping the spawn() call in try/catch and adding an 'error' listener, both routing to runWithDart().
  • Root-caused the v0.9.36 release run failure: build-native-binaries (macos-13, x64) can no longer schedule because GitHub retired the macos-13 hosted runner, and current x64 macOS runner images require the paid large-runner tier. create-release requires every build-native-binaries matrix entry to succeed, so that one failure silently skipped create-release for the whole release — npm/pub.dev/vscode all published v0.9.36, but no GitHub Release or binaries were ever created, which is why the npm wrapper's download URLs 404. Dropped the macos-13/x64 matrix entry and its dependents (Homebrew SHA256 computation + on_intel block) rather than switching to a paid runner label, since that needs org-level runner/billing configuration I can't confirm is set up. npm/VSCode/IntelliJ already fall back to the Dart runtime when a native binary 404s, so Intel Mac users lose only the native-binary fast path; Homebrew on Intel now fails formula resolution with Homebrew's standard unsupported-platform error instead of trying to install a binary that no longer exists.

Test plan

  • node -c bin/cli.js — syntax check passes
  • Simulated a 0-byte cached binary → confirmed existing size-check fallback still reaches Dart runtime cleanly
  • Simulated a non-empty but non-executable cached binary (reproduces the exact ENOEXEC synchronous-throw crash) → confirmed it now logs a warning and falls back to Dart instead of crashing
  • Simulated a valid executable in the cache path → confirmed the native-binary happy path is unaffected
  • python3 -c "import yaml; yaml.safe_load(...)" — release.yml parses as valid YAML after the matrix/Homebrew edits
  • Full release.yml run end-to-end (requires a real v* tag push — not exercised here)

Generated with Claude Code

…cOS x64 CI target

runNativeBinary() had no handler for spawn() launch failures. On this
platform spawn() throws ENOEXEC synchronously for a non-executable
cached binary, and other failure modes (EACCES, wrong-arch) surface
async via the 'error' event - neither path was covered, so any bad
cached binary crashed the CLI instead of falling back to the Dart
runtime that main() already implements for the "binary missing" case.

Separately, the v0.9.36 release run failed because build-native-binaries
(macos-13, x64) can no longer schedule: GitHub retired the macos-13
hosted runner, and current x64 macOS runner images require the paid
large-runner tier. create-release requires every build-native-binaries
matrix entry to succeed, so that one failure silently skipped
create-release for the whole release - npm/pub.dev/vscode all
published v0.9.36, but no GitHub Release or binaries were ever created,
which is why the npm wrapper's download URLs were 404ing.

Dropped the macos-13/x64 matrix entry and its dependents (Homebrew
SHA256 + on_intel block) rather than switching to a paid runner label,
since that requires org-level runner/billing configuration this repo
may not have. npm, VSCode, and IntelliJ already fall back to the Dart
runtime when a native binary 404s, so Intel Mac users are unaffected
beyond losing the native-binary fast path; Homebrew on Intel now fails
formula resolution with Homebrew's standard unsupported-platform error
instead of installing a binary that no longer exists.

Constraint: macos-13 hosted runner is fully retired, not just deprecated
Constraint: current x64 macOS runner labels (macos-14-large, macos-15-large) require paid large-runner tier
Rejected: relabel matrix to macos-14/macos-15 without -large | those bare labels are arm64, would silently mislabel an arm64 binary as x64
Rejected: switch to macos-15-large | unconfirmed whether org has large-runner billing/runner-group configured; would fail differently instead of fixing anything
Confidence: high
Scope-risk: moderate
Directive: if Intel Mac native-binary support is restored later, do it via a paid large runner explicitly opted into, not by reusing a bare macos-1x label
Not-tested: full release.yml run end-to-end (requires a real v* tag push); validated via YAML syntax check and manual matrix/heredoc diff review only

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@charliewwdev
charliewwdev merged commit 3111b48 into ai-dashboad:main Aug 21, 2026
4 of 5 checks passed
@JohnGalt1717

Copy link
Copy Markdown

Can we get this pushed to NPM please? The current npm release doesn't fix this.

JuanCordovaLazo pushed a commit to JuanCordovaLazo/flutter-skill that referenced this pull request Nov 7, 2026
The native-binary spawn crash was fixed in ai-dashboad#55, but the fallback it
reaches was itself broken in three ways (issues ai-dashboad#45, ai-dashboad#49, ai-dashboad#50).

- `spawn('dart', ...)` cannot launch the Windows SDK entrypoints, which
  are .bat scripts CreateProcess refuses to execute. It failed with the
  same `spawn UNKNOWN` reported against the native path, and had no
  error handling, so the process crashed. Spawn through a shell on
  Windows, quoting arguments by hand since a shell does none, and guard
  both the synchronous throw and the async 'error' event.
- The prerequisite check only looked for Dart. The vendored package
  depends on package:flutter, so `dart pub get` can never resolve it and
  the run died with "Couldn't resolve the package 'flutter_skill'" —
  which names the wrong problem. Require Flutter and say so.
- `flutter pub get` failures were swallowed by an empty catch, so the
  real reason was discarded and the failure surfaced later as an
  unrelated import error. Report the output and stop.

Also stops a failed binary download from poisoning later installs: a
404 or connection error left behind the empty file createWriteStream had
already opened, and the "already installed" check only tested for
existence, so the download was never retried. Remove the partial file on
failure and treat a zero-byte file as absent.
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.

3 participants