can1357/oh-my-pi · error · Error

patch does not apply: {message}

Error message

patch does not apply: {message}

What it means

Error::PatchFailed is raised when a patch did not apply — context mismatch, missing target file, or malformed patch input. The message includes the human-readable reason and, when known, the offending path.

Source

Thrown at crates/pi-vcs/src/error.rs:56

	/// auto-resolved to HEAD). Callers should skip and continue the range —
	/// replaces the historical `/the previous cherry-pick is now empty/` stderr
	/// regex.
	#[error("cherry-pick of {sha} is empty")]
	EmptyCherryPick {
		/// The commit that collapsed to a no-op.
		sha: String,
	},

	/// A merge-style operation (cherry-pick, stash pop, 3-way apply) hit
	/// conflicting changes.
	#[error("merge conflict in {} file(s)", paths.len())]
	Conflict {
		/// Worktree-relative paths left in a conflicted state.
		paths: Vec<String>,
	},

	/// A patch did not apply (context mismatch, missing file, malformed input).
	#[error("patch does not apply: {message}")]
	PatchFailed {
		/// Human-readable reason, including the offending path when known.
		message: String,
	},

	/// A CLI-backed operation (push/fetch/clone, reftable fallback) exited
	/// non-zero. Carries the captured streams for user-facing error surfaces.
	#[error("{}", crate::error::cli_message(command, *exit_code, stdout, stderr))]
	Cli {
		/// Rendered command line (`git push --no-follow-tags …`).
		command:   String,
		/// Process exit code.
		exit_code: i32,
		/// Captured stdout (may be truncated).
		stdout:    String,
		/// Captured stderr (may be truncated).
		stderr:    String,
	},

View on GitHub (pinned to 9690622007)

Solutions

  1. Regenerate the patch against the current HEAD (`git diff` from an up-to-date base) and retry.
  2. Apply with more fuzz/context tolerance if the API allows it (equivalent of `git apply -C1 --3way`).
  3. Check the file in `message` — restore/rename it if the patch expects a path that moved, or rewrite the patch paths.
  4. If the patch text was mangled in transit, transfer it as a file/bytes (preserving LF) instead of pasting.

Example fix

// before
repo.apply_patch(text)?; // context mismatch, hard error
// after
match repo.apply_patch(text) {
    Err(Error::PatchFailed { message, .. }) if message.contains("context") => {
        repo.apply_patch_3way(text)?; // retry with 3-way merge
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}
Defensive patterns

Strategy: try-catch

Type guard

fn is_patch_failed(err: &pi_vcs::Error) -> bool {
    matches!(err, pi_vcs::Error::PatchFailed { .. })
}

Try / catch

match repo.apply_patch(patch_text) {
    Err(pi_vcs::Error::PatchFailed { message, .. }) => {
        log::warn!("patch rejected: {message}; retrying with 3-way merge");
        repo.apply_patch_3way(patch_text)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Applying a diff whose context lines no longer match the worktree/HEAD content (file edited since the patch was made), applying a diff to a repo where a target file does not exist, or feeding truncated/corrupted diff text into the apply API.

Common situations: Patches emailed or copy-pasted and mangled (whitespace/line-ending drift, CRLF vs LF), diffs against a much older commit, applying AI-generated patches after the file changed, patch line numbers offset beyond fuzz tolerance.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/e751d3ead8ff1d63. Report an issue: GitHub.