{"record":{"id":"0ab4fcb0296202aa","repo":"apple/pkl","slug":"output-file-conflict-output-files-entry-path","errorCode":null,"errorMessage":"Output file conflict: `output.files` entry `\"$pathSpec\"` resolves to file path `$realPath`, which is a directory.","messagePattern":"Output file conflict: `output\\.files` entry `\"\\$pathSpec\"` resolves to file path `\\$realPath`, which is a directory\\.","errorType":"exception","errorClass":"CliException","httpStatus":null,"severity":"error","filePath":"pkl-cli/src/main/kotlin/org/pkl/cli/CliCommandRunner.kt","lineNumber":129,"sourceCode":"    if (outputFiles.isEmpty()) return\n\n    val writtenFiles = mutableMapOf<Path, String>()\n    val outputDir = options.normalizedWorkingDir\n    if (outputDir.exists() && !outputDir.isDirectory()) {\n      throw CliException(\"Output path `$outputDir` exists and is not a directory.\")\n    }\n    for ((pathSpec, fileOutput) in outputFiles) {\n      checkPathSpec(pathSpec)\n      val resolvedPath = outputDir.resolve(pathSpec).normalize()\n      val realPath = if (resolvedPath.exists()) resolvedPath.toRealPath() else resolvedPath\n      val previousOutput = writtenFiles[realPath]\n      if (previousOutput != null) {\n        throw CliException(\n          \"Output file conflict: `output.files` entries `\\\"${previousOutput}\\\"` and `\\\"$pathSpec\\\"` resolve to the same file path `$realPath`.\"\n        )\n      }\n      if (realPath.isDirectory()) {\n        throw CliException(\n          \"Output file conflict: `output.files` entry `\\\"$pathSpec\\\"` resolves to file path `$realPath`, which is a directory.\"\n        )\n      }\n      writtenFiles[realPath] = pathSpec\n      realPath.createParentDirectories()\n      realPath.writeBytes(fileOutput.bytes)\n      val displayPath =\n        if (Path.of(pathSpec).isAbsolute) pathSpec\n        else IoUtils.relativize(resolvedPath, currentWorkingDir).toString()\n      errStream.writeText(displayPath + IoUtils.getLineSeparator())\n      errStream.flush()\n    }\n  }\n\n  class SynthesizedRunCommand(\n    private val spec: CommandSpec,\n    private val runner: CliCommandRunner,\n    name: String? = null,","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-cli/src/main/kotlin/org/pkl/cli/CliCommandRunner.kt#L111-L147","documentation":"writeMultipleFileOutput checks each resolved output path before writing; this error means one of the `output.files` pathSpec entries resolves to an existing directory, so the CLI cannot write a file at that path and aborts with a conflict error.","triggerScenarios":"An `output.files` pathSpec (after placeholder substitution and path resolution against the output dir) matches an existing directory — e.g. pattern `\"%{moduleName}\"` where a directory with that name exists, or a previously-created directory layout left behind by another run.","commonSituations":"Reusing an output directory where a prior run created subdirectories; pathSpec patterns ending up empty so the spec resolves to the output dir itself; collisions between file output names and multi-file-output subdirectories.","solutions":["Remove or rename the directory at the reported path, then re-run.","Adjust the `output.files` pathSpec to a distinct file path that does not collide with an existing directory.","Clean stale output directories between runs in CI scripts.","Check placeholder substitution results — an empty/odd value can make a spec resolve to a directory."],"exampleFix":"// before\n[\"%{moduleName}\"] = output // resolves to existing dir 'myapp'\n// after\n[\"%{moduleName}.json\"] = output","handlingStrategy":"validation","validationCode":"import java.nio.file.*\nval p = outputDir.resolve(pathSpec).normalize()\nrequire(!Files.isDirectory(p)) { \"pathSpec $pathSpec resolves to existing directory $p\" }","typeGuard":null,"tryCatchPattern":"try {\n  runner.writeMultipleFileOutput(outputFiles)\n} catch (e: CliException) {\n  // clean conflicting paths reported in e.message, then retry\n}","preventionTips":["Clean stale output directories between runs.","Ensure pathSpec patterns always yield file paths (append extension), not bare module names.","Keep single-file and multi-file outputs in separate directory trees."],"tags":["cli","output-conflict","filesystem"],"backgroundTag":"file-already-exists","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}