apple/pkl · error · CliException

Path spec `$pathSpec` contains illegal character `${pathSpec

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.

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)

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.