theonedev/onedev · error · IllegalArgumentException
Illegal escape in patch_fromText: ${line}
Error message
Illegal escape in patch_fromText: ${line} What it means
Inside patch_fromText, each diff line is URL-decoded (UTF-8) before being added to the patch. If the line contains a malformed percent-escape sequence (e.g. a stray '%' not followed by two hex digits), URLDecoder.decode throws IllegalArgumentException, which is rethrown as 'Illegal escape in patch_fromText'. The library requires patch bodies to be properly percent-encoded, so any hand-crafted or corrupted line with invalid escapes fails here.
Source
Thrown at server-core/src/main/java/io/onedev/server/util/diff/DiffMatchPatch.java:2346
while (!text.isEmpty()) {
try {
sign = text.getFirst().charAt(0);
} catch (IndexOutOfBoundsException e) {
// Blank line? Whatever.
text.removeFirst();
continue;
}
line = text.getFirst().substring(1);
line = line.replace("+", "%2B"); // decode would change all "+"
// to " "
try {
line = URLDecoder.decode(line, "UTF-8");
} catch (UnsupportedEncodingException e) {
// Not likely on modern system.
throw new Error("This system does not support UTF-8.", e);
} catch (IllegalArgumentException e) {
// Malformed URI sequence.
throw new IllegalArgumentException("Illegal escape in patch_fromText: " + line,
e);
}
if (sign == '-') {
// Deletion.
patch.diffs.add(new Diff(Operation.DELETE, line));
} else if (sign == '+') {
// Insertion.
patch.diffs.add(new Diff(Operation.INSERT, line));
} else if (sign == ' ') {
// Minor equality.
patch.diffs.add(new Diff(Operation.EQUAL, line));
} else if (sign == '@') {
// Start of next patch.
break;
} else {
// WTF?
throw new IllegalArgumentException("Invalid patch mode '" + sign + "' in: "
+ line);View on GitHub (pinned to d44925c47c)
Solutions
- Find the line reported in the message and fix or remove the malformed % escape (encode a literal % as %25).
- Regenerate the patch via patch_toText so all lines are correctly URL-encoded.
- URL-encode raw content yourself before building patch lines if constructing patches manually.
- Validate patch lines decode cleanly (URLDecoder.decode in a probe call) before passing the whole patch string to the library.
Example fix
// before
String line = "-100% done"; // bare % -> illegal escape
patches = dmp.patch_fromText("@@ -1,1 +1,1 @@\n" + line);
// after
String line = "-" + URLEncoder.encode("100% done", "UTF-8");
patches = dmp.patch_fromText("@@ -1,1 +1,1 @@\n" + line); Defensive patterns
Strategy: validation
Validate before calling
void validatePatchLine(String line) {
try {
new java.net.URLDecoder().decode(line.substring(1), "UTF-8");
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Bad percent-escape in patch line: " + line);
}
} Try / catch
try {
patches = patch_fromText(text);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Illegal escape")) { /* re-encode or reject */ }
else throw e;
} Prevention
- URL-encode all diff content with URLEncoder before building patch lines.
- Never insert raw '%' into patch lines; encode as %25.
- Probe-decode lines yourself before calling patch_fromText.
When it happens
Trigger: patch_fromText reads a +/-/space-prefixed line whose content, after stripping the mode character, contains an invalid URI escape such as '%zz', '%', or a truncated '%A' at end of line.
Common situations: Manual editing of patch strings that introduced a literal %; double-encoding or partial decoding of patch text by an intermediate system; copying patch text through a tool that mangles percent characters; truncated storage cutting an escape sequence in half.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Invalid patch string: ${text.getFirst()}
- Invalid patch mode '${sign}' in: ${line}
- Last appearance of @ is a surprise to me. Either use @...@ t
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/3ed7f4bc35f3c43b.
Report an issue: GitHub.