Recovering from a Failed Upgrade After Removing :clojure-version in Clojure 1.12
0 reputation · 27 Nov 2021, 04:31 UTC
0 reputation · 27 Nov 2021, 04:31 UTC
When upgrading to Clojure 1.12 the :clojure-version key was dropped from deps.edn, requiring an explicit org.clojure/clojure dependency. If the new default pulls in incompatible transitive dependencies, the application may crash or fail tests, and the tools.deps lockfile may contain conflicting entries that are not automatically updated.
The goal is to return to a known‑working state without corrupting the lockfile or re‑introducing the removed key. Constraints include the fact that tools.deps does not regenerate the lockfile when a dependency is changed, and that the lockfile format may evolve in future releases. Developers must therefore pin versions explicitly and understand how the lockfile is applied during a build.
What is the safest sequence to restore the lockfile to a previously verified state after a failed upgrade? How should a project pin the Clojure version in deps.edn once the :clojure-version key is no longer supported? What command pattern guarantees that the lockfile reflects the pinned dependency without manual edits, ensuring consistent resolution across environments?
35275 reputation · 27 Nov 2021, 14:25 UTC
To safely restore your project to a known-working state after a failed upgrade, you must eliminate the current resolution state and force a clean re-computation. Because tools.deps does not automatically regenerate the lockfile when deps.edn is modified, follow this sequence:
deps.edn: Roll back your deps.edn file to the last known-good commit..cpcache/ directory. This removes the existing lockfiles and cached classpaths, preventing the tool from attempting to reconcile the failed upgrade state with the reverted configuration.clojure -P to create a fresh lockfile based on the reverted deps.edn.clojure -M:test) to confirm the environment is stable before attempting the upgrade again.With the removal of the :clojure-version key, Clojure is now treated as a standard dependency. To pin a specific version, add org.clojure/clojure directly to your :deps map.
{:deps
{org.clojure/clojure {:mvn/version "1.12.0"}
;; other dependencies here
}}
Note: Do not leave the old :clojure-version key in the file. While it is ignored in version 1.12 and later, keeping it creates configuration drift and confusion for other developers.
To ensure the lockfile reflects your pinned dependencies across all environments without manual editing, use the following command pattern:
clojure -P -Sforce
The -P flag generates the lockfile, and -Sforce forces the re-computation of the classpath. This combination ensures that any changes to the :deps map—including the transition from :clojure-version to an explicit dependency—are fully realized in the lockfile.
After running the recovery or upgrade, verify the resolved graph using:
clojure -Stree
Check the output to ensure org.clojure/clojure is listed at the expected version and that no conflicting transitive versions of the Clojure runtime are present. If you encounter a version conflict that -Sforce does not resolve, you may need to add a direct dependency for the conflicting transitive library to override the resolution.
Diagnostic Detail: If the above steps do not resolve the crash, please specify if you are using a custom :mvn/local-repo or an offline mirror, as this can interfere with how clojure -P fetches artifacts.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.