babashka

reefersleep 2025-06-25T08:30:25.027999Z

Our Jenkins CICD is experiencing something weird where a series of bb tasks are run just fine, but then one fails with

Clojure tools not yet in expected location: ...
And throws a FileNotFoundException: something/something/somtehing/.deps.clj/TRANSACTION_START (Permission denied) An odd aspect of it is that the ones that run successfully actually run a bit more involved code, where the one that fails just attempts to run (println false). I assume it's besides the point. There's plenty of other tasks that are defined in the exact same manner and run without issue. This is an intermittent problem. I suppose it's a Jenkins problem more than a babashka problem, but maybe someone here has encountered something similar?

reefersleep 2025-06-26T07:24:08.794859Z

Yeah, it sounds far fetched because it's so nonsensical.

reefersleep 2025-06-26T14:24:34.030149Z

Still picking apart this problem.

borkdude 2025-06-25T08:31:04.418709Z

This might be due to one task not having deps and another one having deps?

reefersleep 2025-06-25T08:32:16.245169Z

I looked for that too, they have exactly the same :requires

borkdude 2025-06-25T08:32:27.710789Z

The file is written by deps.clj where it wants to unpack the tools jar: https://github.com/borkdude/deps.clj/blob/ad71e665843f133c164ffd73d3444f8b81580eea/src/borkdude/deps.clj#L415 you can set this location manually with DEPS_CLJ_TOOLS_DIR https://github.com/borkdude/deps.clj/tree/master?tab=readme-ov-file#deps_clj_tools_dir

borkdude 2025-06-25T08:32:52.333089Z

is there :extra-deps or perhaps babashka.deps/add-deps somewhere

borkdude 2025-06-25T08:33:40.697319Z

If the project is open source, I'd have a look

reefersleep 2025-06-25T08:34:55.028629Z

Thank you, it's not 😞 There's :extra-deps for the :test alias (which runs without issue for the build I'm looking at)

reefersleep 2025-06-25T08:35:34.435859Z

I did see the thing about manually setting DEPS_CLJ_TOOLS_DIR in the README, but I thought it not relevant since other tasks run without issue?

reefersleep 2025-06-25T08:36:25.037899Z

Thanks for the links, I was in doubt about where to find TRANSACTION_START in source.

reefersleep 2025-06-25T09:41:31.551439Z

My coworker suspects it's to do with Jenkins nodes swapping work mid-process, or something to do with them sharing the file system, or something to that effect.

borkdude 2025-06-25T09:46:02.751149Z

In that case set the env variable to some stable disk

reefersleep 2025-06-25T10:08:12.200289Z

Indeed 🙂 Need to know more about the Jenkins environment.

james 2025-06-25T16:44:25.560379Z

If you change Jenkins agent mid-build you will most likely lose any files you had downloaded.

gaverhae 2025-06-30T07:38:06.200729Z

These days Docker files often change the user towards the end of their setup as Dockerfiles start out as root and you want to run your app as a less privileged user. Changing the user would likely change the meaning of ~.

🧐 1
gaverhae 2025-06-30T07:38:54.046069Z

That shouldn't be intermittent though 🤔

reefersleep 2025-06-27T09:22:24.641619Z

Is there an easy way to determine where Clojure Tools was put by an initial call to bb prepare so that I can se DEPS_CLJ_TOOLS_DIR to that path?

borkdude 2025-06-27T09:23:44.411629Z

you should see logs of the tools jar being downloaded if it's not there yet

borkdude 2025-06-27T09:25:35.776049Z

if you don't set anything, it will use the HOME environment directory

borkdude 2025-06-27T09:25:46.726489Z

so $HOME/.deps.clj

borkdude 2025-06-27T09:26:24.243239Z

on my system that is:

~/.deps.clj/1.12.1.1550/ClojureTools/clojure-tools-1.12.1.1550.jar

reefersleep 2025-06-27T09:28:08.849579Z

Yes, I see. The thing is, I'm trying to call bb prepare in a RUN command in a dockerfile, and it seems like that ends up somewhere else (or with a different version) than when I call bb prepare while the container is actually running at some later point. So I'm thinking I have to extract the path during the initial download, set DEPS_CLJ_TOOLS_DIR - all in the Dockerfile RUN commands - and then have future bb calls use that when the container is running.

borkdude 2025-06-27T09:28:54.673809Z

why not set DEPS_CLJ_TOOLS_DIR to some predicable location, always?

borkdude 2025-06-27T09:29:31.189849Z

so first set the env var, then download with bb prepare

reefersleep 2025-06-27T09:29:42.561789Z

oh, you're right

reefersleep 2025-06-27T09:29:46.264169Z

! 😄

reefersleep 2025-07-01T11:36:23.372139Z

I think that the problem lies in various containers running on the Jenkins agent (or whatever it's called) and they are not all guaranteed to know the same files.

reefersleep 2025-07-01T11:37:33.665369Z

Learning a lot about our Jenkins setup these days, but it's very slow to iterate changes onto. It's a big mistake that we can't run it locally. Soooo slow.

james 2025-07-01T11:39:07.599479Z

You will need to fetch the files you need when you switch agent e.g. do a source checkout again. In kubernetes you would have a new pod with a new agent if that is what you use.

reefersleep 2025-07-01T11:51:54.364449Z

I catch what you're saying. The switch is not explicit in our Jenkins.k8s script, which is why I tried to bake in bb prepare to the Dockerfile - I thought I could preempt the problem. I still think I can, I just need to follow @gaverhae’s note about RUN and runtime users.

reefersleep 2025-07-01T11:52:05.769689Z

Or, at least I need to try that out 🙂

reefersleep 2025-07-01T11:55:56.169469Z

Part of the problem is also that I don't have the keys to the murkiest machine room - another team owns the infrastructure. But I was fortunate to get help from one of them today and got some great insights.

dominic 2025-06-25T13:45:21.736669Z

I’m hitting a very strange issue - I am using latest bb release but can recreate in prior versions. • I have a top-level :deps • I also have an :extra-deps in the task, which then pulls a bunch of other deps (all bb compatible). ◦ The deps are git-libs but the transitive deps are maven deps (in case that matters). ◦ One of the transitive deps is malli which pulls in fipp - I am using latest here. • If I put all my deps in :deps or all of them in :extra-deps, then this issue doesn’t happen. It’s only when I have both that I hit the issue. If it try and run my task, I hit an issue in fipp:

----- Error --------------------------------------------------------------------
Type:     clojure.lang.ExceptionInfo
Message:  Could not resolve symbol: clojure.instant/thread-local-utc-date-format
Data:     {:type :sci/error, :line 32, :column 1, :file "fipp/ednize.clj", :phase "analysis"}
Location: fipp/ednize.clj:71:26
Phase:    analysis

----- Context ------------------------------------------------------------------
67:   ;TODO Eduction ??
68: 
69:   java.util.Date
70:   (-edn [x]
71:     (let [s (format-hack #'clojure.instant/thread-local-utc-date-format x)]
                             ^--- Could not resolve symbol: clojure.instant/thread-local-utc-date-format
72:       (tagged-literal 'inst s)))
73: 
74:   ;TODO (defmethod print-method java.util.Calendar
75: 
76:   java.sql.Timestamp

----- Stack trace --------------------------------------------------------------
fipp.ednize/format-hack                   - fipp/ednize.clj:71:26
fipp.ednize/format-hack                   - fipp/ednize.clj:27:1
fipp.ednize/let                           - fipp/ednize.clj:71:13
fipp.ednize                               - fipp/ednize.clj:71:5
BUT it’s clearly from an older version of fipp as format-hack no longer exists (specifically to enable bb compatibility). I’ll try and create a minimal bb file that can recreate this issue but have been unsuccessful so far - wondering if it’s a known issue or if there’s an obvious cause.

borkdude 2025-06-25T13:46:43.195929Z

yeah, a repro would be helpful

borkdude 2025-06-25T13:47:01.507929Z

to work around the issue, perhaps including a newer version of fipp would help

dominic 2025-06-25T13:49:10.809649Z

I guess the question is include it where? if i specify latest in my extra-deps it doesn’t help 🤔

borkdude 2025-06-25T13:51:07.727549Z

if you execute your task with --debug you should see some babashka.deps/add-deps call at the top, this will maybe help

borkdude 2025-06-25T13:51:36.613229Z

bb --debug your:task

dominic 2025-06-25T13:54:26.775689Z

so some more info - the lib I’m pulling in does this in core.clj:

(mi/instrument!)
((requiring-resolve 'malli.dev/start!))
looking at the debug stack trace saw that requiring-resolve was the source of the issue, and indeed removing it I now no longer hit the issue

borkdude 2025-06-25T13:55:53.003509Z

perhaps you're pulling in an older version of malli which depends on fipp?

dominic 2025-06-25T13:56:56.188919Z

I’m on latest malli - and I’ve specified latest fipp in my deps It’s the fact that it only happens if I split my deps between top level deps and extra-deps in the task that confuses me the most

borkdude 2025-06-25T13:57:38.918809Z

sure. is it possible to still share the babashka.deps/add-deps call it produces when it goes wrong?

dominic 2025-06-25T14:00:07.675759Z

sure:

(babashka.deps/add-deps '{:deps {com.kroo/infreify {:local/root "../infreify"}, fipp/fipp {:mvn/version "0.6.27"}}}) 

dominic 2025-06-25T14:00:41.513979Z

this infreify lib is what pulls in malli and calls ! on load

borkdude 2025-06-25T14:01:42.333619Z

you could also print the classpath your tasks uses with:

{:tasks (do (prn (babashka.classpath/get-classpath)) 
            (your-normal-task))}

👀 1
borkdude 2025-06-25T14:02:16.523789Z

to see if it pulls in an older version of fipp or malli

👍 1
dominic 2025-06-25T14:09:45.325009Z

OK yes I’m getting 0.6.17, even if malli is 0.19.1 - is there a way with bb to see the deps resolution like you can with deps or lein?

borkdude 2025-06-25T14:11:30.489609Z

can you try bb -Sforce your-task perhaps?

borkdude 2025-06-25T14:11:36.909659Z

perhaps it's a caching issue

borkdude 2025-06-25T14:12:37.541529Z

and which bb version are we talking here?

borkdude 2025-06-25T14:12:55.586999Z

dep resolution, sadly no

dominic 2025-06-25T14:13:23.347159Z

> and which bb version are we talking here? 1.12.204

dominic 2025-06-25T14:16:26.699219Z

OK some more useful info which explains the difference. If I have deps + extra-deps, I have 2 versions of fipp on my classpath (0.6.17 and 0.6.27, in that order) - so my guess is that bb resolves each set of deps independently and then just concats them together? So I should be able to work around that by making sure my top level deps also include more recent version of fipp as well

borkdude 2025-06-25T14:21:36.669749Z

a repro would be useful here. For this bb.edn

{:deps {fipp/fipp {:mvn/version "0.6.17"}}
 :tasks {a {:extra-deps {fipp/fipp {:mvn/version "0.6.27"}}
            :task (prn (babashka.classpath/get-classpath))}}}
I see this:
$ bb --debug a

(babashka.deps/add-deps '{:deps {fipp/fipp {:mvn/version "0.6.27"}}}) ;; deps
and:
"/Users/borkdude/.m2/repository/fipp/fipp/0.6.17/fipp-0.6.17.jar:/Users/borkdude/.m2/repository/org/clojure/core.rrb-vector/0.0.14/core.rrb-vector-0.0.14.jar:/Users/borkdude/.m2/repository/fipp/fipp/0.6.27/fipp-0.6.27.jar:/Users/borkdude/.m2/repository/org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2.jar"

borkdude 2025-06-25T14:22:00.064039Z

So the top level dep stays on front of the classpath and is loaded first. add-deps simply concatenates more stuff

dominic 2025-06-25T14:22:51.868069Z

Yeah that makes sense - but in this case doesn’t it mean it’s likely to use the first one that’s loaded?

borkdude 2025-06-25T14:23:55.010139Z

In this case fipp 0.6.17 will be used

borkdude 2025-06-25T14:24:31.352709Z

yeah, if you already load the dep, it won't be reloaded

dominic 2025-06-25T14:26:24.315809Z

yeah it makes sense now - do you know if this is how extra-deps behaves when using aliases in deps.edn?

borkdude 2025-06-25T14:26:58.865999Z

I don't think that's how extra-deps behaves in deps.edn. I could probably try to make bb behave closer to that

dominic 2025-06-25T14:27:41.183379Z

yeah I mean it would avoid this specific type of edge case, don’t know how complicated it would be to modify and whether it’s worth the effort 😄

borkdude 2025-06-25T14:28:12.000179Z

I'm still interested in the repro though, just to understand the issue. since you're not specifying an older malli anywhere how does it get on the classpath for example.

borkdude 2025-06-25T14:28:29.621739Z

and didn't -Sforce help

dominic 2025-06-25T14:33:15.772739Z

ah sorry your example is a good repro of the main issue which is another version of fipp on the classpath - in my case it turns out the lib in the top level deps pulls in babashka itself - so the same code can be run in clojure I think, and actually just for fs and processso I’ll probably pull those in explicitly instead babashka pulls in nubank/matcher-combinators 3.6.0 (in test profile?) which pull in midje/midje 1.10.6 which pulls in mvxcvi/puget 1.1.2 which pulls in fipp/fipp 0.6.17

dominic 2025-06-25T14:35:45.575509Z

here’s a repro:

{:deps {babashka/babashka {:mvn/version "1.12.204"}}
 :tasks
 {my-task {:extra-deps {metosin/malli {:mvn/version "0.19.1"}}
           :requires ([malli.core])
           :task (do ((requiring-resolve 'malli.dev/start!))
                     (println "running my task!"))}}}

borkdude 2025-06-25T14:36:03.869399Z

babashka doesn't depend on matcher combinators, at least not directly. it's not recommended to directly depend on babashka for bb scripts. it's not intended to be used that way. you can use bb print-deps to get deps.edn with dependencies that you can run in the JVM

borkdude 2025-06-25T14:36:10.851869Z

so please stop doing that :)

dominic 2025-06-25T14:36:50.118379Z

I mean it’s imported in the underlying lib that’s pulled in by the script, not the script itself, in my case

borkdude 2025-06-25T14:36:56.073819Z

babashka's deps.edn top level deps contain a lot of crap that is only used for testing

dominic 2025-06-25T14:36:57.074469Z

but yeah, I’ll remove the dep on babashka in the other lib

dominic 2025-06-25T14:38:53.239829Z

bb print-deps is cool though, didn’t know about that 👍