apple/pkl · error · CliException

Cannot download packages because no cache directory is…

Error message

Cannot download packages because no cache directory is specified.

What it means

`pkl package download` requires a module cache directory to store downloaded packages; when none is configured (no `--cache-dir`, no `PKL_CACHE_DIR`, etc.) the downloader throws immediately in doRun before resolving anything.

Solutions

  1. Pass `--cache-dir /path/to/cache` on the command line.
  2. Set the `PKL_CACHE_DIR` environment variable to a writable directory.
  3. Ensure HOME (or XDG_CACHE_HOME) is set so the default cache location can be derived.

Example fix

# before
pkl package download package://example.com/foo@1.0.0
# after
PKL_CACHE_DIR=$HOME/.pkl/cache pkl package download package://example.com/foo@1.0.0
Defensive patterns

Strategy: validation

Validate before calling

if (System.getenv("PKL_CACHE_DIR") == null && !Files.isDirectory(Path.of(System.getProperty("user.home"), ".pkl/cache"))) {
  throw IllegalStateException("no Pkl cache directory configured; set PKL_CACHE_DIR")
}

Try / catch

try {
  pklCli.runPackageDownload(args)
} catch (e: CliException) {
  if ("no cache directory" in (e.message ?: "")) {
    exec("pkl package download --cache-dir ${cacheDir()} ...")
  } else throw e
}

Prevention

When it happens

Trigger: Running `pkl package download ...` in an environment where the cache directory is null — e.g. a minimal container or CI job without `PKL_CACHE_DIR` set and without a user cache dir.

Common situations: Docker images run with a stripped HOME; CI runners that unset XDG env vars; hermetic test environments that intentionally disable caching.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/90dacd8b5df3d445. Report an issue: GitHub.

Appendix: source

Thrown at pkl-cli/src/main/kotlin/org/pkl/cli/CliPackageDownloader.kt:32

 * limitations under the License.
 */
package org.pkl.cli

import org.pkl.commons.cli.CliBaseOptions
import org.pkl.commons.cli.CliCommand
import org.pkl.commons.cli.CliException
import org.pkl.core.packages.PackageResolver
import org.pkl.core.packages.PackageUri

class CliPackageDownloader(
  baseOptions: CliBaseOptions,
  private val packageUris: List<PackageUri>,
  private val noTransitive: Boolean,
) : CliCommand(baseOptions) {

  override fun doRun() {
    if (moduleCacheDir == null) {
      throw CliException("Cannot download packages because no cache directory is specified.")
    }
    val packageResolver = PackageResolver.getInstance(securityManager, httpClient, moduleCacheDir)
    val errors = mutableMapOf<PackageUri, Throwable>()
    for (pkg in packageUris) {
      try {
        packageResolver.downloadPackage(pkg, pkg.checksums, noTransitive)
      } catch (e: Throwable) {
        errors[pkg] = e
      }
    }
    when (errors.size) {
      0 -> return
      1 ->
        throw CliException(
          errors.values.single().message
            ?: ("An unexpected error occurred: " + errors.values.single())
        )
      else ->

View on GitHub (pinned to f3efcbfc9b)