Skip to content

[BUG]: auto-load kills the host process with the child's abort exit code (0xC0000409) and no error on Windows #1209

Closed

Description

@Noisemaker111

Summary

On Windows, when the varlock CLI child process dies abnormally (in our case from a Node.js libuv teardown assertion, exit code 0xC0000409 / STATUS_STACK_BUFFER_OVERRUN), varlock/auto-load calls process.exit() in the parent process with that raw abort code and prints nothing useful. The host tool that imported varlock/auto-load (for us the Alchemy CLI, but any framework/build script is affected) dies mid-command with exit code -1073740791 and zero diagnostics.

Environment

  • Windows 11
  • Node v24.18.0 (reproduced on v24.19.0; works on v24.20.0+ and v22.23.3)
  • varlock 1.18.0
  • Host: alchemy 2.0.0-beta.81 (bun 1.3.14)

Repro

In any project where varlock/auto-load is imported (our case: the IaC entry file does import "varlock/auto-load"), run the CLI child directly:

node_modules\.bin\varlock load --format json-full --compact

Output: the normal JSON is printed to stdout, then:

Assertion failed: !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c, line 94

Exit code: -1073740791 (0xC0000409).

Through auto-load, the same child failure kills the parent process. Running alchemy logs produced exactly one line of output before dying:

INFO: Importing stack module
Assertion failed: !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c, line 94
exit: -1073740791

The host never got to print any error of its own. (node_modules\.bin\varlock.exe is Bun's bin shim; it resolves node from PATH, which is why the installed Node version decides whether this fires. Pinning an older Node on PATH makes it exit 0 — which is how we currently work around it.)

Root cause on the varlock side

dist/auto-load.mjs's catch block:

} catch (err) {
  if (err instanceof VarlockExecError && err.stderr) process.stderr.write(err.stderr);
  else console.error(err);
  const exitCode = err.exitCode ?? 1;
  ...
  process.exit(exitCode);   // <-- propagates the child's 0xC0000409 to the host
}

When the child dies with a native abort code, err.stderr is empty (the libuv assertion goes to the C runtime, not through the pipe), so the host gets no error message at all — just a silent process.exit(-1073740791).

Requested fixes

  1. Do not propagate raw Windows abort codes (>= 0xC0000000) as the host's exit code. Map them to 1 and print a clear message, e.g. varlock env resolution failed: the varlock CLI crashed (exit code 0xC0000409). Run "varlock load" manually to see the underlying error.
  2. Include the failing child's command line and exit status in that message.
  3. Consider also surfacing the child's stdout on failure — in this mode the CLI actually produced its full JSON output before aborting, which is valuable context.
  4. Related: auto-load: DEP0190 warning on Windows from execFileSync(varlock.cmd, args, { shell: true }) #1137 covers the Windows execFileSync(varlock.cmd, args, { shell: true }) fallback in the same helper.

Note for triage: the underlying Node assertion is a Node bug (nodejs/node#64322 family) that was fixed in Node v24.20.0 — bisected: v24.18.0 and v24.19.0 crash, v24.20.0 exits 0. The bug above is the reason a single crashing child takes down every embedding tool with an opaque exit code, regardless of the cause.

Activity

  1. pullfrog commented on Oct 10, 2026

    @pullfrog
    Contributor
  2. pullfrog commented on Oct 10, 2026

    @pullfrog
    Contributor

    Implemented in PR #1210: auto-load maps native CLI crash statuses to host exit code 1 and reports the invoked command and original status, while keeping potentially secret-bearing stdout available to error hooks rather than printing it. All 2,438 Varlock tests passed (13 skipped), along with lint, typecheck, package build, and docs build; Windows crash statuses were simulated on Linux, not reproduced natively.

    Task list (4/4 completed)
    • Read issue discussion and inspect auto-load process handling
    • Implement regression fix, tests, and user-facing documentation
    • Run verification and independent self-review
    • Commit, push, and open a pull request

    Pullfrog  | View workflow run | via Pullfrog | Using gpt-6.1-sol | 𝕏

  3. theoephraim commented on Oct 10, 2026

    @theoephraim
    Member

    Thanks for this. Will get it sorted out asap.

  4. github-actions commented on Oct 13, 2026

    @github-actions
    Contributor

    ✅ A fix has been merged to main in #1210 and will ship in the next release. GitHub auto-closed this issue on merge, but the change isn't published yet.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions