apache/beam · error · IllegalArgumentException

quoted identifier cannot contain unescaped quote

Error message

quoted identifier cannot contain unescaped quote

What it means

unescapeFieldName() scans the inner content of a backtick-quoted identifier and throws this IllegalArgumentException if it encounters a bare backtick that is not escaped as \`. Quoted Firestore identifiers must escape any backtick characters they contain.

Source

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

        }
      }
      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 != '\\') {
          buf.append(c);
        } else if (i + 1 >= fieldName.length()) {
          throw new IllegalArgumentException("illegal trailing backslash");
        } else {
          i++;
          switch (fieldName.charAt(i)) {
            case 'a':
              buf.appendCodePoint(Ascii.BEL); // "Alert" control character
              break;
            case 'b':
              buf.append('\b');

View on GitHub (pinned to 12126d8942)

Solutions

  1. Escape every literal backtick inside the quoted segment as \`
  2. Escape backslashes too (\) since they begin escape sequences
  3. Prefer renaming the field to avoid backticks if you control the schema

Example fix

// before
OrderByFieldPath.fromString("doc.`my`field`");
// after
OrderByFieldPath.fromString("doc.`my\\`field`");
Defensive patterns

Strategy: validation

Validate before calling

public static String escapeQuotedIdentifier(String name) {
  return "`" + name.replace("\\", "\\\\").replace("`", "\\`") + "`";
}

Try / catch

try {
  OrderByFieldPath p = OrderByFieldPath.fromString(rawPath);
} catch (IllegalArgumentException e) {
  // retry with properly escaped segments
}

Prevention

When it happens

Trigger: A backtick-quoted identifier whose content contains an unescaped ` character, e.g. fromString("a.`my`field`") — the inner backtick terminates the quote in the outer regex but any surviving raw ` inside the unescaped content is rejected.

Common situations: Field names that themselves contain backticks (rare but possible in Firestore) configured without the required \` escape; generated paths that concatenate identifiers without escaping.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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