apple/pkl · error · CliException

Path spec `$pathSpec` contains illegal character

Error message

Path spec `$pathSpec` contains illegal character `${pathSpec[illegal]}`.

What it means

checkPathSpec validates user-supplied output path specs (patterns used with multi-file output) before any files are written. If the spec contains a character that IoUtils considers reserved/illegal in filenames (other than the allowed '/'), it throws CliException naming the offending character. This prevents generating files with names the OS cannot represent or that could escape the output directory.

Solutions

  1. Remove or replace the illegal character reported in the message; keep only legal filename characters and '/'.
  2. Quote the path spec properly in your shell so Pkl receives the intended characters.
  3. If you need directory structure, use '/' separators rather than OS-specific separators or reserved chars.

Example fix

// before
val spec = "out: @{name}.xml"

// after
val spec = "out/@{name}.xml"
Defensive patterns

Strategy: validation

Validate before calling

// reject specs containing characters outside [A-Za-z0-9._@{}-/] before invoking the CLI
fun isSafePathSpec(spec: String) =
  spec.all { it.isLetterOrDigit() || it in "._-/@{}" }

Type guard

fun String?.asSafePathSpec(): String? =
  this?.takeIf { it.isNotEmpty() && it.none { c -> IoUtils.isReservedFilenameChar(c) && c != '/' } }

Try / catch

try {
  writeMultipleFileOutput(pathSpec, ...)
} catch (e: CliException) {
  if (e.message?.contains("illegal character") == true) {
    println("Fix your --output-path spec: ${e.message}")
  } else throw e
}

Prevention

When it happens

Trigger: Calling writeMultipleFileOutput / passing a --output-path pattern (e.g. with globs or templating) that includes characters like ':', '*', '?', '"', '<', '>', '|', or control characters, when running `pkl test --junit-dir` style or project output commands that write multiple files.

Common situations: Copying a Windows-style path with drive colon into a path spec; embedding a glob asterisk where it is not allowed; template placeholders producing characters like '?' or quotes; shell quoting mangles the spec before Pkl sees it.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at pkl-cli/src/main/kotlin/org/pkl/cli/OutputUtils.kt:27

 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.pkl.cli

import java.io.OutputStream
import org.pkl.commons.cli.CliException
import org.pkl.core.util.IoUtils

fun checkPathSpec(pathSpec: String) {
  val illegal = pathSpec.indexOfFirst { IoUtils.isReservedFilenameChar(it) && it != '/' }
  if (illegal == -1) {
    return
  }
  throw CliException("Path spec `$pathSpec` contains illegal character `${pathSpec[illegal]}`.")
}

fun OutputStream.writeText(text: String) = write(text.toByteArray())

fun OutputStream.writeLine(text: String) {
  writeText(text)
  writeText("\n")
}

View on GitHub (pinned to f3efcbfc9b)