Skip to content

The "versions/all" endpoint returns nothing for some candidates #94

Description

@jvasileff

Normally, the versions/all api endpoint returns a CSV list of versions, for example:

% curl -s https://api.sdkman.io/2/candidates/gradle/darwinarm64/versions/all
0.7,0.8,0.9,0.9.1,0.9.2,1.0,1.1,1.10,1.11,1.12,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.1,2.10,2.11,2.12,2.13,2.14,2.14.1,2.2,2.2.1,2.3,2.4,2.5,2.6,2.7,2.8,2.9,3.0,3.1,3.2,3.2.1,3.3,3.4,3.4.1,3.5,3.5.1,4.0,4.0.1,4.0.2,4.1,4.10,4.10.1,4.10.2,4.10.3,4.2,4.2.1,4.3,4.3.1,4.4,4.4.1,4.5,4.5.1,4.6,4.7,4.8,4.8.1,4.9,5.0,5.1,5.1.1,5.2,5.2.1,5.3,5.3.1,5.4,5.4.1,5.5,5.5.1,5.6,5.6.1,5.6.2,5.6.3,5.6.4,6.0,6.0.1,6.1,6.1.1,6.2,6.2.1,6.2.2,6.3,6.4,6.4.1,6.5,6.5.1,6.6,6.6.1,6.7,6.7.1,6.8,6.8.1,6.8.2,6.8.3,6.9,6.9.1,6.9.2,6.9.3,6.9.4,7.0,7.0.1,7.0.2,7.1,7.1.1,7.2,7.3,7.3.1,7.3.2,7.3.3,7.4,7.4.1,7.4.2,7.5,7.5.1,7.6,7.6.1,7.6.2,7.6.3,7.6.4,7.6.5,7.6.6,8.0,8.0.1,8.0.2,8.1,8.1.1,8.10,8.10.1,8.10.2,8.11,8.11.1,8.12,8.12.1,8.13,8.14,8.14.1,8.14.2,8.14.3,8.14.4,8.14.5,8.2,8.2.1,8.3,8.4,8.5,8.6,8.7,8.8,8.9,9.0.0,9.1.0,9.2.0,9.2.1,9.3.0,9.3.1,9.4.0,9.4.0-rc-1,9.4.0-rc-2,9.4.1,9.5.0,9.5.0-rc-1,9.5.0-rc-2,9.5.0-rc-3,9.5.0-rc-4,9.5.1,9.6.0,9.6.0-rc-1,9.6.0-rc-2,9.6.0-rc-3,9.6.1%

But for some candidates, the list is empty:

curl -s https://api.sdkman.io/2/candidates/jmc/darwinarm64/versions/all

I asked Claude Fable to take a look, and the AI came up with the following. The bug is of course real, but as a disclaimer, I haven't looked at the code myself. The AI suggested patch is very small, so hopefully it will make sense to anyone familiar with the codebase.


sdkman-candidates: versions/all returns empty for platform-specific candidates registered as UNIVERSAL

Current behavior

/2/candidates/{candidate}/{platform}/versions/all returns an empty body for jmc,
mvnd, scalacli, mcs, and jextract on every platform, while versions/list shows
their versions:

$ curl -s https://api.sdkman.io/2/candidates/jmc/darwinarm64/versions/all
                                                          # (empty)
$ curl -s "https://api.sdkman.io/2/candidates/jmc/darwinarm64/versions/list" | sed -n 4,6p
     9.1.1-zulu
     9.1.1-adpt
     9.1.1.1-zulu

Reason

These candidates carry distribution: "UNIVERSAL" in the candidates collection
(the sdkman-db-migrations Candidate DSL default; their migrations never set it),
but their version rows are per-platform (MAC_ARM64, LINUX_64, …).

VersionsController.all trusts that field and substitutes UNIVERSAL for the
requested platform, so the query matches no rows. VersionsListController.list
passes the requested platform straight through, and
findAllVersionsByCandidatePlatform already includes UNIVERSAL rows via
or(equal("platform", platform), equal("platform", "UNIVERSAL")) — so the
substitution is never needed and only harms.

Patch

--- a/app/controllers/VersionsController.scala
+++ b/app/controllers/VersionsController.scala
   def all(candidate: String, platformId: String) = Action.async(parse.anyContent) { request =>
-    candidatesRepo.findCandidate(candidate).flatMap { candidateO =>
-      val universal    = candidateO.map(_.distribution).contains("UNIVERSAL")
-      val distribution = if (universal) "UNIVERSAL" else Platform(platformId).distribution
-
-      versionsRepo.findAllVersionsByCandidatePlatform(candidate, distribution).map { versions =>
-        Ok(versions.map(_.version).mkString(","))
-      }
+    versionsRepo.findAllVersionsByCandidatePlatform(candidate, Platform(platformId).distribution).map { versions =>
+      Ok(versions.map(_.version).mkString(","))
     }
   }

(candidatesRepo and its injection become unused. Alternatively, fix the data:
a db-migrations changeset correcting distribution for the affected candidates —
but the code fix also protects future registrations from the same default.)

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