theonedev/onedev · error · IllegalArgumentException
Invalid patch mode ' ' in
Error message
Invalid patch mode '${sign}' in: ${line} What it means
While parsing diff lines inside a patch, patch_fromText expects each line to start with a mode character: ' ' (equal), '-' (delete), '+' (insert), or '@' (start of the next patch). Any other first character is unrecognized and triggers 'Invalid patch mode'. This prevents ambiguous or corrupted patch bodies from being silently misapplied.
Solutions
- Check the offending line and add/restore the required mode prefix (' ', '-', or '+').
- Do not feed raw unified diffs ('diff --git'/'index' lines) into patch_fromText; strip them or regenerate with patch_toText.
- Re-encode patch lines so leading spaces survive transport (URL-encoding handles this); beware editors/HTML that trim leading spaces.
- Wrap parsing in try-catch for IllegalArgumentException to reject corrupt patches cleanly.
Example fix
// before String patch = "@@ -1,1 +1,1 @@\nhello"; // missing mode char // after String patch = "@@ -1,1 +1,1 @@\n hello"; // ' ' = context/equal line
Defensive patterns
Strategy: validation
Validate before calling
boolean validPatchBody(java.util.List<String> lines) {
return lines.stream().skip(1) // skip header
.allMatch(l -> l.isEmpty() || " +-@".indexOf(l.charAt(0)) >= 0);
} Try / catch
try {
patches = patch_fromText(text);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Invalid patch mode")) { /* sanitize or reject */ }
else throw e;
} Prevention
- Ensure every body line begins with ' ', '-', or '+'.
- Strip non-patch lines (diff --git, index) before parsing.
- Beware transports that strip leading spaces; keep URL-encoding intact.
When it happens
Trigger: A line inside a patch body begins with a character other than ' ', '-', '+', or '@' — e.g. a line missing its mode prefix, a unified-diff line prefixed differently, or text accidentally concatenated into the patch body.
Common situations: Hand-editing patch text and dropping the leading +/- character; mixing standard unified diff output (lines like 'diff --git' or 'index ...') into patch_fromText input; copy/paste losing leading spaces at line starts.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/766941fb3073377c.
Report an issue: GitHub.
Appendix: source
Thrown at server-core/src/main/java/io/onedev/server/util/diff/DiffMatchPatch.java:2363
// 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);
}
text.removeFirst();
}
}
return patches;
}
/**
* Class representing one diff operation.
*/
public static class Diff {
/**
* One of: INSERT, DELETE or EQUAL.
*/
public Operation operation;
/**View on GitHub (pinned to d44925c47c)