apple/pkl · error · CliException
Output path `$outputDir` exists and is not a directory.
Error message
Output path `$outputDir` exists and is not a directory.
What it means
Before writing multiple-file output, CliCommandRunner.writeMultipleFileOutput verifies that the working-directory-derived output path, if it already exists, is a directory. This error means the target output location exists as a regular file (or other non-directory), so per-file outputs cannot be written beneath it.
Source
Thrown at pkl-cli/src/main/kotlin/org/pkl/cli/CliCommandRunner.kt:116
}
/**
* Renders the command's `output.files`, writing each entry as a file.
*
* File paths are written to the standard error stream.
*
* Unlike CliEvaluator, command outputs write relative to --working-dir and may write files
* anywhere in the filesystem. This is intentionally less sandboxed than `pkl eval` and directly
* targets the capabilities of CLI tools written in general purpose languages. Pkl commands should
* therefore be treated as untrusted code the way that any other CLI tool would be.
*/
fun writeMultipleFileOutput(outputFiles: Map<String, FileOutput>) {
if (outputFiles.isEmpty()) return
val writtenFiles = mutableMapOf<Path, String>()
val outputDir = options.normalizedWorkingDir
if (outputDir.exists() && !outputDir.isDirectory()) {
throw CliException("Output path `$outputDir` exists and is not a directory.")
}
for ((pathSpec, fileOutput) in outputFiles) {
checkPathSpec(pathSpec)
val resolvedPath = outputDir.resolve(pathSpec).normalize()
val realPath = if (resolvedPath.exists()) resolvedPath.toRealPath() else resolvedPath
val previousOutput = writtenFiles[realPath]
if (previousOutput != null) {
throw CliException(
"Output file conflict: `output.files` entries `\"${previousOutput}\"` and `\"$pathSpec\"` resolve to the same file path `$realPath`."
)
}
if (realPath.isDirectory()) {
throw CliException(
"Output file conflict: `output.files` entry `\"$pathSpec\"` resolves to file path `$realPath`, which is a directory."
)
}
writtenFiles[realPath] = pathSpec
realPath.createParentDirectories()View on GitHub (pinned to f3efcbfc9b)
Solutions
- Delete or rename the existing file at the output path so the tool can create a directory there.
- Point the output path/working dir at an empty directory instead.
- If the file is a previous single-file output you still need, move it elsewhere before re-running.
- Check the path in your script/CI config — it may reference a file rather than a directory.
Example fix
# before $ pkl eval -m out ... # where `out` is an existing file rm out # after $ mkdir -p out && pkl eval -m out ...
Defensive patterns
Strategy: validation
Validate before calling
import java.nio.file.*
val p = Path.of(outputPath)
require(!(Files.exists(p) && !Files.isDirectory(p))) { "Output path $p exists and is not a directory" } Try / catch
try {
runner.writeMultipleFileOutput(outputFiles)
} catch (e: CliException) {
System.err.println(e.message)
} Prevention
- Ensure the multiple-file output path is either nonexistent or a directory.
- Remove stale single-file outputs before switching to multi-file output mode.
- Use distinct paths for single-file and multiple-file output in scripts.
When it happens
Trigger: Running a pkl command with multiple-file output (output.files) while options.normalizedWorkingDir points at an existing regular file — e.g. a stale file created by a previous single-file-output run at the same path.
Common situations: Switching from single-file output to multiple-file output without removing the old output file; a script that created a file where a directory is expected; wrong --output-path or working directory flag.
Related errors
- Output file `$outputFile` is a directory. Did you mean `--mu
- Output path `$outputDir` exists and is not a directory.
- Output file conflict: `output.files` entries `"${previousOut
- Output file conflict: `output.files` entry `"$pathSpec"` res
- Cannot substitute output path placeholder `%{moduleDir}` bec
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/136a28e9590ccba0.
Report an issue: GitHub.