Skip to content

[BUG] CEL string extension functions (substring, lastIndexOf, etc) fail to compile in protovalidate-java #438

@kolaworld

Description

@kolaworld

Description

protovalidate-java does not register CEL string extension functions. Rules using substring() or lastIndexOf() compile and validate in protovalidate-go but fail at runtime in Java with undeclared reference.

Steps to Reproduce

  1. Define a message with a CEL rule that uses substring() or lastIndexOf():
syntax = "proto3";

package test.v1;

import "buf/validate/validate.proto";

message CreateRequest {
  string parent = 1;
  string path = 2;

  option (buf.validate.message).cel = {
    id: "path_matches_parent"
    message: "path must be a child of parent"
    expression:
      "this.path.lastIndexOf('/') >= 0 && "
      "this.path.substring(0, this.path.lastIndexOf('/')) == this.parent"
  };
}
  1. Validate a CreateRequest instance using protovalidate-java.

Expected Behavior

The CEL rule compiles and validates the message, matching the behavior of protovalidate-go.

Actual Behavior

Validation fails during CEL compilation:

ERROR: <input>:1:12: undeclared reference to 'lastIndexOf' (in container '')
 | this.path.lastIndexOf('/') >= 0 && this.path.substring(0, this.path.lastIndexOf('/')) == this.parent
 | ...........^
ERROR: <input>:1:46: undeclared reference to 'substring' (in container '')
 | this.path.lastIndexOf('/') >= 0 && this.path.substring(0, this.path.lastIndexOf('/')) == this.parent
 | .............................................^

Environment

  • Operating System: macOS
  • Compiler/Toolchain: JDK 25 (Temurin 25.0.2), Kotlin/JVM, gRPC
  • Protobuf Compiler & Version: buf
  • Protovalidate Version: build.buf:protovalidate:1.1.1

Possible Solution

ValidatorImpl.java builds the CEL environment without registering string extensions:

CelFactory.standardCelBuilder()
    .addCompilerLibraries(validateLibrary)
    .addRuntimeLibraries(validateLibrary)

cel-java already provides SUBSTRING and LAST_INDEX_OF via CelExtensions.strings(). Registering that library in the validator's CEL environment should fix this.

Additional Context

The same schema validates correctly in Go. The issue appears to be that protovalidate-java does not enable the cel-java string extension library, not that the Java CEL runtime lacks the capability.

Metadata

Metadata

Assignees

Labels

BugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions