apple/pkl · error · ParserError
interpolationInConstant
interpolationInConstant
Error message
String constant cannot have interpolated values.
What it means
The Pkl parser throws this when a string constant (e.g. a module/property name such as `foo` in backticks-less plain constant strings) contains an interpolation sequence (`\(...)`) which is only allowed in string literals, not in string constants used as identifiers. The lexer delivers an INTERPOLATION_START token inside the constant string and the parser rejects it.
Solutions
- Remove the `\(...)` interpolation and write the fully expanded string constant literally
- Compute the name in Pkl code instead (e.g. build the string as a value and use a computed property / dynamic object key if the grammar allows)
- If the target API requires an identifier, generate the source text with a script rather than interpolating in the constant
Example fix
// before foo\(bar) = 1 // string constant with interpolation // after foobar = 1 // or compute the name in a dynamic object
Defensive patterns
Strategy: validation
Validate before calling
// before invoking the parser, reject interpolations in constant strings
const INTERP = /\\\(/;
function assertConstantString(s) {
if (INTERP.test(s)) throw new Error(`String constant cannot have interpolated values: ${s}`);
} Type guard
function isConstantString(tok) {
return typeof tok === 'string' && !tok.includes('\\(');
} Try / catch
try {
parser.parseModule(source);
} catch (e) {
if (e.code === 'interpolationInConstant') {
console.error(`Replace \\(...) in the string constant at ${e.span}`);
} else throw e;
} Prevention
- Never use \\(...) inside identifier-position strings (module/property names)
- Generate dynamic names via computed properties or dynamic objects instead
- Run `pkl format`/lint in CI to catch constant-string mistakes early
When it happens
Trigger: Writing an interpolated expression like `"value \(1+1)"`-style `\(...)` inside a string constant that the grammar requires to be constant, e.g. a module name, property name, or other identifier-position string.
Common situations: Dynamically constructing a property/module name or AMQP-like constant string with a template expression; copy-pasting a normal string literal into an identifier position; refactoring code that moved a computed name into a constant position.
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
- Cannot parse ` ` as number.
- cannotAmendLocalPropertyDefinition
- cannotDefineExternalMember
- '" + ch + "'
- closingStringDelimiterMustBeginOnNewLine
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/57db7d0e88df7619.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-parser/src/main/java/org/pkl/parser/ParserImpl.java:1634
}
case STRING_ESCAPE_QUOTE -> {
next();
builder.append('"');
}
case STRING_ESCAPE_BACKSLASH -> {
next();
builder.append('\\');
}
case STRING_ESCAPE_RETURN -> {
next();
builder.append('\r');
}
case STRING_ESCAPE_UNICODE -> builder.append(parseUnicodeEscape(next()));
case EOF -> {
var delimiter = new StringBuilder(startTk.text(lexer)).reverse().toString();
throw parserError("missingDelimiter", delimiter);
}
case INTERPOLATION_START -> throw parserError("interpolationInConstant");
// the lexer makes sure we only get the above tokens inside a string
default -> throw new RuntimeException("Unreacheable code");
}
}
var end = next().span;
return new StringConstant(builder.toString(), start.endWith(end));
}
private String getEscapeText(FullToken tk) {
return switch (tk.token) {
case STRING_ESCAPE_NEWLINE -> "\n";
case STRING_ESCAPE_QUOTE -> "\"";
case STRING_ESCAPE_BACKSLASH -> "\\";
case STRING_ESCAPE_TAB -> "\t";
case STRING_ESCAPE_RETURN -> "\r";
case STRING_ESCAPE_CONTINUATION -> "";
case STRING_ESCAPE_UNICODE -> parseUnicodeEscape(tk);
default -> throw new RuntimeException("Unreacheable code");View on GitHub (pinned to f3efcbfc9b)