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

  1. Switch to indexOfOrNull(pattern) and handle null, e.g. `s.indexOfOrNull(sep) ?? 0`.
  2. Check membership first with s.contains(pattern) before calling indexOf.
  3. Normalize case/whitespace (toLowerCase, trim) on both string and pattern when formatting may vary.
  4. 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

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


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