apache/beam · error · IllegalArgumentException

quoted identifier cannot be empty

Error message

quoted identifier cannot be empty

What it means

unescapeFieldName() validates the inner content of a backtick-quoted Firestore identifier; if the quoted content is empty (``) it throws this IllegalArgumentException. Firestore identifiers must contain at least one character even when quoted.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/firestore/QueryUtils.java:251

    @Override
    public int compareTo(OrderByFieldPath other) {
      // Inspired by com.google.cloud.firestore.FieldPath.
      int length = Math.min(this.getSegments().size(), other.getSegments().size());
      for (int i = 0; i < length; i++) {
        byte[] thisField = this.getSegments().get(i).getBytes(StandardCharsets.UTF_8);
        byte[] otherField = other.getSegments().get(i).getBytes(StandardCharsets.UTF_8);
        int cmp = UnsignedBytes.lexicographicalComparator().compare(thisField, otherField);
        if (cmp != 0) {
          return cmp;
        }
      }
      return Integer.compare(this.getSegments().size(), other.getSegments().size());
    }

    private static String unescapeFieldName(String fieldName) {
      if (fieldName.isEmpty()) {
        throw new IllegalArgumentException("quoted identifier cannot be empty");
      }
      StringBuilder buf = new StringBuilder();
      for (int i = 0; i < fieldName.length(); i++) {
        char c = fieldName.charAt(i);
        // Roughly speaking, there are 4 cases we care about:
        //   - carriage returns: \r and \r\n
        //   - unescaped quotes: `
        //   - non-escape sequences
        //   - escape sequences
        if (c == '`') {
          throw new IllegalArgumentException("quoted identifier cannot contain unescaped quote");
        } else if (c == '\r') {
          buf.append('\n');
          // Convert '\r\n' into '\n'
          if (i + 1 < fieldName.length() && fieldName.charAt(i + 1) == '\n') {
            i++;
          }
        } else if (c != '\\') {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Replace the empty quoted segment with the actual field name
  2. If the segment is dynamic, validate the interpolated field name is non-empty before building the path
  3. Remove the empty segment entirely if it is not needed

Example fix

// before
String path = "user.`" + subField + "`.email"; // subField == ""
// after
if (subField == null || subField.isEmpty()) {
  throw new IllegalArgumentException("subField must be non-empty");
}
String path = "user.`" + subField + "`.email";
Defensive patterns

Strategy: validation

Validate before calling

public static boolean hasNonEmptyQuotedSegments(String path) {
  java.util.regex.Matcher m = Pattern.compile("`([^`]*)`").matcher(path);
  while (m.find()) {
    if (m.group(1).isEmpty()) return false;
  }
  return true;
}

Try / catch

try {
  OrderByFieldPath p = OrderByFieldPath.fromString(path);
} catch (IllegalArgumentException e) {
  LOG.warn("Empty quoted identifier in field path '{}'", path, e);
}

Prevention

When it happens

Trigger: Parsing a field path whose segment is an empty backtick pair, e.g. fromString("``") or fromString("a.``.b") — the quoted identifier has no content to unescape.

Common situations: Copy/paste errors leaving `` in sort field config, template/interpolation that produced an empty field name inside backticks (e.g. `"` + field + `"` where field is empty).

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/c7ca4f35a6cd0f95. Report an issue: GitHub.