Skip to content
Latchkey

tools.build "No such var" / "Wrong number of args" in CI

A build.clj using tools.build referenced a var that is not defined in the required namespace, or called a build function with the wrong number of arguments. The compiler or runtime rejects the call before the build runs.

What this error means

A clojure -T:build run fails with "Syntax error compiling ... No such var: b/copy-dir" or "Execution error ... Wrong number of args (N) passed to ...".

clj
Syntax error compiling at (build.clj:18:3).
No such var: b/uber
Execution error (ArityException) Wrong number of args (1) passed to: clojure.tools.build.api/compile-clj

Common causes

A misspelled or wrong tools.build var

The alias points at clojure.tools.build.api, but the function name is wrong or belongs to a different version of the API.

A call with the wrong argument shape

tools.build functions take a single options map; passing positional args or the wrong keys raises an arity or key error.

How to fix it

Call the real function with an options map

  1. Require the tools.build api with a stable alias.
  2. Use the correct function name and pass a single options map.
  3. Run clojure -T:build <fn> to confirm.
build.clj
(require '[clojure.tools.build.api :as b])
(b/compile-clj {:basis basis :class-dir class-dir :src-dirs ["src"]})
(b/uber {:class-dir class-dir :uber-file "target/app.jar" :basis basis})

Pin the tools.build version

Pin the git coordinate so the API surface your build.clj uses is stable across runs.

deps.edn
{:build {:deps {io.github.clojure/tools.build {:git/tag "v0.10.5" :git/sha "2a21b7a"}}
         :ns-default build}}

How to prevent it

  • Pin tools.build to a known version and match its API.
  • Pass a single options map to each build function.
  • Run the build task locally before relying on it in CI.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →