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
In multiple-file output mode, CliEvaluator.writeMultipleFileOutput validates each per-module output directory: if the target directory path exists but is not a directory (e.g. a regular file), it throws CliException because file outputs cannot be placed there.
Source
Thrown at pkl-cli/src/main/kotlin/org/pkl/cli/CliEvaluator.kt:235
private fun toModuleSource(uri: URI, reader: InputStream) =
if (uri == VmUtils.REPL_TEXT_URI) {
ModuleSource.create(uri, reader.readAllBytes().toString(StandardCharsets.UTF_8))
} else {
ModuleSource.uri(uri)
}
/**
* Renders each module's `output.files`, writing each entry as a file into the specified output
* directory.
*/
private fun writeMultipleFileOutput(builder: EvaluatorBuilder) {
val outputDirs = directoryOutputPaths!!
val writtenFiles = mutableMapOf<Path, OutputFile>()
builder.setOutputFormat(options.outputFormat).build().use { evaluator ->
for ((moduleUri, outputDir) in outputDirs) {
if (outputDir.exists() && !outputDir.isDirectory()) {
throw CliException("Output path `$outputDir` exists and is not a directory.")
}
val moduleSource = toModuleSource(moduleUri, inputStream)
val output = evaluator.evaluateOutputFiles(moduleSource)
val realOutputDir = if (outputDir.exists()) outputDir.toRealPath() else outputDir
for ((pathSpec, fileOutput) in output) {
checkPathSpec(pathSpec)
val (realPath, resolvedPath) = realOutputDir.resolveRealPath(Path.of(pathSpec))
if (!realPath.startsWith(realOutputDir)) {
throw CliException(
"Output file conflict: `output.files` entry `\"$pathSpec\"` in module `$moduleUri` resolves to file path `$realPath`, which is outside output directory `$realOutputDir`."
)
}
val previousOutput = writtenFiles[realPath]
if (previousOutput != null) {
throw CliException(
"Output file conflict: `output.files` entries `\"${previousOutput.pathSpec}\"` in module `${previousOutput.moduleUri}` and `\"$pathSpec\"` in module `$moduleUri` resolve to the same file path `$realPath`."
)View on GitHub (pinned to f3efcbfc9b)
Solutions
- Delete or move the existing file at the reported outputDir path so a directory can be created.
- Verify the --multiple-file-output-path argument points to a directory location.
- Add cleanup (`rm -f <path>` or equivalent) to scripts before multi-file output runs.
- Separate single-file and multi-file output locations to avoid collisions.
Example fix
# before $ pkl eval -m build/out ... # build/out is a stale file # after $ rm build/out && mkdir -p build/out && pkl eval -m build/out ...
Defensive patterns
Strategy: validation
Validate before calling
import java.nio.file.Files
import java.nio.file.Path
for ((_, dir) in outputDirs) {
require(!Files.exists(dir) || Files.isDirectory(dir)) { "Output path $dir exists and is not a directory" }
} Try / catch
try {
ev.writeMultipleFileOutput(builder)
} catch (e: CliException) {
System.err.println(e.message)
} Prevention
- Ensure each --multiple-file-output-path target is absent or a directory before running.
- Add pre-run cleanup of stale outputs in CI pipelines.
- Keep single-file and multi-file output locations separate.
When it happens
Trigger: Running pkl with --multiple-file-output-path(s) where one of the resolved directory output paths exists as a regular file — commonly a leftover single-file output or a wrong flag value.
Common situations: Previous runs wrote a file at the path now used as the multi-file output dir; CI caches a stale file; a typo merges the output dir path with a filename.
Related errors
- Output path `$outputDir` exists and is not a directory.
- Output file `$outputFile` is a directory. Did you mean `--mu
- 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/4f7d7ffe4ba161eb.
Report an issue: GitHub.