flowable/flowable-engine · error · ScanException

invalid escape sequence \\

Error message

invalid escape sequence \\

What it means

Scanner.nextString() throws ScanException('invalid escape sequence \X') when a backslash inside a string literal is followed by a character other than backslash, single quote, or double quote. Only \\, \', and \" are valid escapes; anything else is rejected at the position where the string started.

Solutions

  1. Replace unsupported escapes with the three supported ones (\\, \', or \") or remove the backslash.
  2. Use expression composition (concatenation, function calls) instead of escape sequences for special characters.
  3. Precompute the desired string in Java/config and reference it as a variable instead of embedding escapes in EL.

Example fix

// before
String expr = "${'line1\nline2'}"; // invalid \n escape
// after
String expr = "${'line1' + newLineVar + 'line2'}";
Defensive patterns

Strategy: validation

Validate before calling

private static final Pattern INVALID_ESCAPE = Pattern.compile("\\\\(?!['\\\\\\\"])");
boolean hasBadEscape(String expr) { return INVALID_ESCAPE.matcher(expr).find(); }

Try / catch

try {
    builder.build(expr);
} catch (TreeBuilderException e) {
    if (String.valueOf(e.getMessage()).startsWith("invalid escape sequence")) {
        throw new IllegalArgumentException("Only \\\\, \\' and \\\" escapes are allowed in EL strings: " + expr);
    }
    throw e;
}

Prevention

When it happens

Trigger: A string literal inside an EL expression containing an escape like '\n', '\t', or '\d' — e.g. "${'a\nb'}" — because the scanner does not support those escapes.

Common situations: Developers copying regexes or Java string conventions (\n, \t, \uXXXX) into EL string literals; expressions built by code that assumed Java-style escaping; regex patterns passed as EL strings.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/2276c93b9a72e10a. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/Scanner.java:317

	/**
	 * string token
	 */
	protected Token nextString() throws ScanException {
		builder.setLength(0);
		char quote = input.charAt(position);
		int i = position+1;
		int l = input.length();
		while (i < l) {
			char c = input.charAt(i++);
			if (c == '\\') {
				if (i == l) {
					throw new ScanException(position, "unterminated string", quote + " or \\");
				} else {
					c = input.charAt(i++);
					if (c == '\\' || c == '\'' || c == '\"') {
						builder.append(c);
					} else {
						throw new ScanException(position, "invalid escape sequence \\" + c, "\\', \\\" or \\\\");
					}
				}
			} else if (c == quote) {
				return token(Symbol.STRING, builder.toString(), i - position);
			} else {
				builder.append(c);
			}
		}
		throw new ScanException(position, "unterminated string", String.valueOf(quote));
	}
	
	/**
	 * number token
	 */
	protected Token nextNumber() throws ScanException {
		int i = position;
		int l = input.length();
		while (i < l && isDigit(input.charAt(i))) {

View on GitHub (pinned to d6d39ce1c6)