babashka 2026-07-18

For some reason when I run tests using bb under Codex it says something like: > The tests emitted non-fatal sandbox-related sysctl cleanup warnings, but completed successfully with exit code 0. I'm just curious what that could be about?

Have you asked codex? :-)

1

That was going to be my next move 🤣

> Yes—more precisely, it’s a Babashka process-cleanup robustness bug exposed by the sandbox. > The sandbox blocks macOS process enumeration via sysctl. babashka.process calls Java’s ProcessHandle.descendants() while cleaning up child processes and fails to catch that permission error, producing the stack trace. > So: > • The permission restriction is environmental. > • The noisy uncaught exception is Babashka’s bug/compatibility issue.

> The bug is in the bundled babashka/process library, specifically destroy-tree, not in the task runner itself. > The call chain is: > 1. Babashka’s wrapper delegates shell directly to process/shell. src/babashka/impl/process.clj > 2. shell defaults :shutdown to destroy-tree. process.cljc > 3. When the child exits, process* removes the registered JVM shutdown hook and then explicitly starts that hook as a thread. There is no exception handling around (shutdown res). process.cljc > 4. destroy-tree unconditionally calls: >

(.descendants handle)
> That is the exact failing expression—line 172 in Babashka v1.12.218, matching the stack trace. process.cljc > Under the restricted macOS environment, Java implements descendants() by enumerating processes through sysctl; that operation returns EPERM. The resulting RuntimeException escapes the shutdown thread. > So there are two related defects: > • Primary: destroy-tree assumes process-tree enumeration cannot fail and has no fallback. > • Secondary: process* executes shutdown callbacks asynchronously without catching/reporting failures in a controlled way. > The narrowest fix belongs in destroy-tree: catch the process-enumeration failure, destroy the root handle as a fallback, and avoid an uncaught cleanup-thread exception. Catching it only in process* would suppress the symptom but leave destroy-tree itself unsafe for direct callers. > The main Babashka repository embeds babashka/process as a submodule, so the actual patch should be made in babashka/process, followed by updating the submodule pointer in babashka/babashka.

Doesn't seem like a big deal, but because Codex runs babashka in a sandbox, the call to (.descendants handle) throws an error due to the sandbox. I'm not sure it's really a bug as AI says, suggestion to just swallow the error doesn't seem a good idea to me, not sure what can be done.

You can file it as a GitHub issue with a repro to think more about it

Is there already a 1.13 compatible Babashka branch?

Not yet but I was planning to release next week

❤️ 1