Skip to content

bbin-installed scripts inherit undesired bb.edn from CWD #113

Description

@yuhan0

bbin-generated wrapper scripts use the shebang #!/usr/bin/env bb, which causes bb to resolve deps from the CWD's bb.edn before any script code runs. If invoked in a dir with a bb.edn with unresolvable deps/paths, the script crashes.

Even without a crash this feels like surprising behavior - I would expect bbin binaries to behave as global tools (like with npm i -g or uv tool install which do not implicitly resolve against project deps.)

Repro:

  • cd to a directory containing:
;; repro/bb.edn
{:deps {broken/lib {:local/root "../nonexistent"}}}
  • Try running any standalone bbin binary eg.
$ bbin install io.github.kkinnear/zprint
$ echo '{1   2 3[4 ]}' | zprint
Error building classpath. Local lib broken/lib not found: /Users/yuhan/nonexistent
Exception in thread "main" clojure.lang.ExceptionInfo:  babashka.process.Process@843c5ed4
        at babashka.process$check.invokeStatic(process.cljc:111)
        at babashka.process$shell.invokeStatic(process.cljc:706)
        at babashka.impl.deps$add_deps$fn__24646.invoke(deps.clj:107)
        at borkdude.deps$_main.invokeStatic(deps.clj:1093)
        at borkdude.deps$_main.doInvoke(deps.clj:912)
        at clojure.lang.RestFn.applyTo(RestFn.java:140)
        at clojure.core$apply.invokeStatic(core.clj:667)
        at babashka.impl.deps$add_deps$fn__24653$fn__24654.invoke(deps.clj:113)
        at clojure.lang.AFn.applyToHelper(AFn.java:152)
        at clojure.lang.AFn.applyTo(AFn.java:144)
        at clojure.core$apply.invokeStatic(core.clj:667)
        at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1990)
        at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1990)
        at clojure.lang.RestFn.invoke(RestFn.java:428)
        at babashka.impl.deps$add_deps$fn__24653.invoke(deps.clj:113)
        at babashka.impl.deps$add_deps.invokeStatic(deps.clj:113)
        at babashka.main$exec$fn__29784.invoke(main.clj:925)
        at clojure.lang.AFn.applyToHelper(AFn.java:152)
        at clojure.lang.AFn.applyTo(AFn.java:144)
        at clojure.core$apply.invokeStatic(core.clj:667)
        at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1990)
        at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1990)
        at clojure.lang.RestFn.invoke(RestFn.java:428)
        at babashka.main$exec.invokeStatic(main.clj:876)
        at babashka.main$main.invokeStatic(main.clj:1296)
        at babashka.main$main.doInvoke(main.clj:1239)
        at clojure.lang.RestFn.applyTo(RestFn.java:140)
        at clojure.core$apply.invokeStatic(core.clj:667)
        at babashka.main$_main.invokeStatic(main.clj:1308)
        at babashka.main$_main.doInvoke(main.clj:1300)
        at clojure.lang.RestFn.applyTo(RestFn.java:140)
        at babashka.main.main(Unknown Source)
        at [email protected]/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)

Note: works as expected when run from another directory or invoked as bb -cp '' ~/.local/bin/zprint - cf. babashka/babashka#1907

I encountered this via running clj-paren-repair-claude-hook (from clojure-mcp-light) in a VM - the hook fires from whatever project directory the editor is in, and the project's bb.edn happened to reference a :local/root dep that was only present on the host machine.

The inner bb calls are fine (

[\"bb\" \"--deps-root\" script-root \"--config\" (str tmp-edn)])
, --config takes precedence), but the outer shebang layer is unprotected.

Possible fix: Change the generated shebang to

#!/usr/bin/env -S bb -cp ''

Related: #78, #110

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