Repository navigation
cabalSpecLatest remains 3.16 in cabal-install 3.18.1.0, causing cabal-version: 3.18 Simple packages to fail #12271
Description
Describe the bug
Cabal-syntax 3.18.1.0 defines and parses CabalSpecV3_18. However, cabalSpecLatest remains CabalSpecV3_16.
This mismatch changes the behaviour of cabal-install. packageSetupScriptStyle treats any non-Custom, non-Hooks package above cabalSpecLatest as a future-format package.
A normal package with cabal-version: 3.18 therefore receives SetupNonCustomExternalLib, not SetupNonCustomInternalLib.
For example, this expression returns SetupNonCustomExternalLib:
packageSetupScriptStyle
(emptyPackageDescription {specVersion = CabalSpecV3_18})The expected result is SetupNonCustomInternalLib. cabal-install 3.18.1.0 links against a Cabal library that supports specification 3.18.
Explicit .cabal parsing recognises cabal-version: 3.18. The problem is the stale default and code that uses it as the supported-version boundary.
To reproduce
Use cabal-install 3.18.1.0:
$ cabal --version
cabal-install version 3.18.1.0
compiled using version 3.18.1.0 of the Cabal libraryCreate repro.cabal:
cabal-version: 3.18
name: repro
version: 0.1.0.0
build-type: Simple
executable repro
main-is: Main.hs
build-depends: base
default-language: Haskell2010Create Main.hs:
main :: IO ()
main = putStrLn "ok"Use an empty setup-executable cache. An existing cache entry can otherwise hide the problem.
setup_cache=$(mktemp -d)
XDG_CACHE_HOME="$setup_cache" cabal build --dry-run
# Succeeds
XDG_CACHE_HOME="$setup_cache" cabal build
# FailsThe failure starts approximately as follows:
[1 of 2] Compiling Main (.../setup/setup.hs, .../setup/Main.o)
setup/setup.hs:2:1: error:
Could not load module ‘Distribution.Simple’.
It is a member of the hidden package ‘Cabal-...’.
The failing Main module is the generated setup wrapper, not the package's Main.hs.
Expected behaviour
The full build must succeed.
A Simple package with cabal-version: 3.18 must use SetupNonCustomInternalLib in cabal-install 3.18.1.0.
What happens internally
- The release recognizes
CabalSpecV3_18, butcabalSpecLatestremainsCabalSpecV3_16. packageSetupScriptStyletherefore classifies the package asSetupNonCustomExternalLib.mkDefaultSetupDepscomputes an implicit dependency onCabal >= 3.17.setImplicitSetupInfomaterializes implicit setup information only forCustomandHooks.- It therefore discards the computed dependency for the
Simplepackage. - The solver sees no setup dependency, so
--dry-runsucceeds. - The elaborated plan nevertheless retains
SetupNonCustomExternalLib. - During execution, cabal compiles the generated
Setup.hswith an empty exclusive dependency set. - The generated setup wrapper cannot import
Distribution.Simple, so the build fails.
Change only the declared specification version:
-cabal-version: 3.18
+cabal-version: 3.16The full build then succeeds.
Proposed fix
-
Publish a Cabal-syntax 3.18 patch release with:
cabalSpecLatest = CabalSpecV3_18
-
Publish a cabal-install patch release with binaries built against the corrected Cabal-syntax release.
The 3.18 release branch must advance only to CabalSpecV3_18.
Current master also defines CabalSpecV3_20 and contains features gated by it. The corresponding change on master must advance cabalSpecLatest to CabalSpecV3_20.
Activity
ffaf1 commentedon Aug 24, 2026
Depressing bug.
A check has to land in CI/checklist too, otherwise we are bound to repeat the mistake.
fix(Cabal-syntax): make CabalSpecV3_20 latest
fix(Cabal-syntax): make CabalSpecV3_18 latest
fix(Cabal-syntax): make CabalSpecV3_20 latest
[-]> cabalSpecLatest remains 3.16 in cabal-install 3.18.1.0, causing cabal-version: 3.18 Simple packages to fail[/-][+]cabalSpecLatest remains 3.16 in cabal-install 3.18.1.0, causing cabal-version: 3.18 Simple packages to fail[/+]andreabedini commentedon Aug 24, 2026
Yes, I was thinking about how to test this in CI. Of the top of my head I cannot think of a reason to not simply use
cabalSpecLatest = maxBound? (there must be a reason just I cannot think of one :)andreabedini commentedon Aug 26, 2026
@ffaf1 Notice I tried to document the proper procedure in #12056
fix(Cabal-syntax): make CabalSpecV3_20 latest
jeffstyr commentedon Sep 13, 2026
Testing that
cabal init --non-interactive && cabal buildsucceeds would be a good functional test to add. (It's particularly embarrassing when following the "Getting Started" guide fails with a strange error.)emilypi commentedon Sep 14, 2026
@jeffstyr I agree with you there. The
--non-interactiveworkflow has exactly one goal: it should be the fastest means to a project that compiles and/or runs available to the user, with a--simplebeing both the fastest and most minimal means to a project that compiles and/or runs. We need regression tests need to reflect that goal. If you want we can assign this one to me and I can get it set up.ulysses4ever commentedon Sep 15, 2026
has this been fixed in
if so, should we close?
zlonast commentedon Sep 21, 2026
@ulysses4ever This fix went only into the 3.18 branch.
ulysses4ever commentedon Sep 21, 2026
@zlonast correct. Now, let’s read the title of the issue… I think either this issue isn’t relevant beyond 3.18 or the title should be generalized to cover other versions.
fix(Cabal-syntax): make CabalSpecV3_18 latest