theonedev/onedev · error · IllegalArgumentException
Invalid patch string: ${text.getFirst()}
Error message
Invalid patch string: ${text.getFirst()} What it means
DiffMatchPatch.patch_fromText parses a textual patch representation and expects each patch to begin with a header line matching patchHeader (e.g. '@@ -start1,len1 +start2,len2 @@'). If the first line of the remaining text does not match this header, the parser cannot determine where a patch starts, so it throws IllegalArgumentException. This guards against corrupted, truncated, or non-patch input being fed into the patch application pipeline.
Source
Thrown at server-core/src/main/java/io/onedev/server/util/diff/DiffMatchPatch.java:2301
* @return List of Patch objects.
* @throws IllegalArgumentException If invalid input.
*/
public List<Patch> patch_fromText(String textline) throws IllegalArgumentException {
List<Patch> patches = new LinkedList<Patch>();
if (textline.length() == 0) {
return patches;
}
List<String> textList = Arrays.asList(textline.split("\n"));
LinkedList<String> text = new LinkedList<String>(textList);
Patch patch;
Pattern patchHeader = Pattern.compile("^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$");
Matcher m;
char sign;
String line;
while (!text.isEmpty()) {
m = patchHeader.matcher(text.getFirst());
if (!m.matches()) {
throw new IllegalArgumentException("Invalid patch string: " + text.getFirst());
}
patch = new Patch();
patches.add(patch);
patch.start1 = Integer.parseInt(m.group(1));
if (m.group(2).length() == 0) {
patch.start1--;
patch.length1 = 1;
} else if (m.group(2).equals("0")) {
patch.length1 = 0;
} else {
patch.start1--;
patch.length1 = Integer.parseInt(m.group(2));
}
patch.start2 = Integer.parseInt(m.group(3));
if (m.group(4).length() == 0) {
patch.start2--;
patch.length2 = 1;View on GitHub (pinned to d44925c47c)
Solutions
- Inspect the line named in the message and ensure the patch text starts with a valid header like '@@ -1,3 +1,4 @@'.
- Regenerate the patch string with DiffMatchPatch.patch_toText instead of hand-writing or hand-editing it.
- If patch text may be unreliable, wrap patch_fromText/patch_apply in try-catch for IllegalArgumentException and reject/repair the input.
- Verify the patch text was not altered in transit (trim trailing whitespace/newlines, check encoding, ensure no truncation).
Example fix
// before
String patchText = storedPatch.substring(storedPatch.indexOf('-')); // strips @@ header
dmp.patch_apply(dmp.patch_fromText(patchText), text);
// after
if (!storedPatch.trim().startsWith("@@")) {
throw new IllegalArgumentException("Stored patch is missing its @@ header");
}
dmp.patch_apply(dmp.patch_fromText(storedPatch.trim()), text); Defensive patterns
Strategy: try-catch
Validate before calling
boolean looksLikePatch(String s) {
return s != null && s.trim().startsWith("@@");
} Try / catch
try {
LinkedList<String> lines = ...;
patches = patch_fromText(lines);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Invalid patch string")) {
// log offending line and reject/repair patch input
} else throw e;
} Prevention
- Always produce patch strings via patch_toText, never by hand.
- Validate patch text starts with '@@' before parsing.
- Store/transfer patch text verbatim; watch for truncation and line-ending mangling.
When it happens
Trigger: Calling DiffMatchPatch.patch_fromText (directly or via patch_apply) with text whose first line is not a valid '@@ -x,y +a,b @@' header: an empty header, hand-edited patch text, a patch with missing leading '@@' line, or concatenation of patch text with unrelated lines.
Common situations: Storing patches in files/DBs that get mangled (line endings, truncation); copying only the diff body without the @@ header; generating patch strings from a different diff library whose format differs; users pasting unified diffs with extra context lines before the first @@.
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/faa7f5b6ff8d6714.
Report an issue: GitHub.