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
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions