apple/pkl · error
doesNotContainLiteralMatch
doesNotContainLiteralMatch
Error message
doesNotContainLiteralMatch
What it means
String.indexOf(pattern) returns the code-point index of the first occurrence of a literal pattern, and throws doesNotContainLiteralMatch when the string does not contain the pattern at all. Pkl deliberately makes the plain indexOf a total failure on missing matches; indexOfOrNull is the null-returning counterpart.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/base/StringNodes.java:354
// inefficient but at least correct
protected boolean eval(String self, VmRegex regex) {
var matcher = regex.matcher(self);
var end = -1;
while (matcher.find()) {
end = matcher.end();
}
return end == self.length();
}
}
public abstract static class indexOf extends ExternalMethod1Node {
@TruffleBoundary
@Specialization
protected long eval(String self, String pattern) {
var charIndex = self.indexOf(pattern);
if (charIndex == -1) {
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder()
.evalError("doesNotContainLiteralMatch")
.withProgramValue("String", self)
.withProgramValue("Pattern", pattern)
.build();
}
return self.codePointCount(0, charIndex);
}
@TruffleBoundary
@Specialization
protected long eval(String self, VmRegex regex) {
var matcher = regex.matcher(self);
if (!matcher.find()) {
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder()
.evalError("doesNotContainRegexMatch")
.withProgramValue("String", self)
.withProgramValue("Pattern", regex)View on GitHub (pinned to f3efcbfc9b)
Solutions
- Switch to indexOfOrNull(pattern) and handle null, e.g. `s.indexOfOrNull(sep) ?? 0`.
- Check membership first with s.contains(pattern) before calling indexOf.
- Normalize case/whitespace (toLowerCase, trim) on both string and pattern when formatting may vary.
- If a default position is acceptable, use the null-coalescing pattern rather than relying on the throw.
Example fix
// before
val idx = s.indexOf("=") // throws when "=" absent
// after
val idx = s.indexOfOrNull("=") ?? -1 Defensive patterns
Strategy: fallback
Validate before calling
// Pkl if (s.contains(pattern)) s.indexOf(pattern) else -1
Type guard
function hasPattern(s: String, p: String): Boolean = s.contains(p)
Try / catch
try { s.indexOf(p) } catch (e: PklError) { -1 } Prevention
- Prefer indexOfOrNull and handle null
- Check contains() before indexing
- Normalize case/whitespace between string and pattern
- Use null-coalescing (??) to supply default indices
When it happens
Trigger: Calling `"abc".indexOf("x")` where the literal substring is absent — including case mismatches ("Hello".indexOf("hello")), whitespace/encoding differences, or pattern strings built at runtime from user config.
Common situations: Parsing config values or paths assuming a separator exists (e.g. "key=value".indexOf("=")); splitting identifiers that may lack a prefix; locale/case differences between producer and consumer of the string.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- doesNotContainRegexMatch
- Cannot convert pkl.base#String `%s` to java.lang.Character b
- charIndexOutOfRange
- type mismatch: value is not of type String
- charIndexOutOfRange
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/fbfb28f361023f76.
Report an issue: GitHub.