helix-editor/helix · error · anyhow::Error
Failed to push to register {name}: clipboard does not match
Error message
Failed to push to register {name}: clipboard does not match register contents What it means
Pushing to '*' or '+' must append to the live system clipboard, so the code first verifies the current clipboard contents still equal what the register last stored (contents_are_saved). If another program (or a clipboard manager) changed the clipboard in between, appending would silently drop that foreign content, so it bails with "clipboard does not match register contents" instead of corrupting state.
Source
Thrown at helix-view/src/register.rs:122
pub fn push(&mut self, name: char, mut value: String) -> Result<()> {
match name {
'_' => Ok(()),
'#' | '.' | '%' => Err(anyhow::anyhow!("Register {name} does not support pushing")),
'*' | '+' => {
let clipboard_type = match name {
'+' => ClipboardType::Clipboard,
'*' => ClipboardType::Selection,
_ => unreachable!(),
};
let contents = self
.clipboard_provider
.load()
.get_contents(&clipboard_type)?;
let saved_values = self.inner.entry(name).or_default();
if !contents_are_saved(saved_values, &contents) {
anyhow::bail!("Failed to push to register {name}: clipboard does not match register contents");
}
saved_values.push(value.clone());
if !contents.is_empty() {
value.push_str(NATIVE_LINE_ENDING.as_str());
}
value.push_str(&contents);
self.clipboard_provider
.load()
.set_contents(&value, clipboard_type)?;
Ok(())
}
_ => {
self.inner.entry(name).or_default().push(value);
Ok(())
}
}View on GitHub (pinned to 079a789e8c)
Solutions
- Overwrite instead of append: a plain write to '*'/'+ resets the register's view of the clipboard and clears the mismatch.
- Accumulate in a named register (a-z) and copy the final result to '+' once, avoiding interleaved OS clipboard use.
- Disable or configure clipboard managers that rewrite contents (trailing-newline trimming is a classic cause).
Example fix
# before
yank to '+', copy elsewhere, push to '+' again # mismatch error
# after
yank to 'a' repeatedly, then :set-register + "#{a:content}" # single final copy Defensive patterns
Strategy: fallback
Validate before calling
fn clipboard_in_sync(registers: &Registers, name: char, provider: &ClipboardProvider) -> bool {
let Ok(current) = provider.load().get_contents(&match name { '+' => ClipboardType::Clipboard, _ => ClipboardType::Selection }) else { return false };
registers.read(name, editor)
.map(|vals| contents_are_saved(&vals.collect::<Vec<_>>(), ¤t))
.unwrap_or(false)
} Try / catch
match registers.push('+', value) {
Err(err) if err.to_string().contains("clipboard does not match") => {
// foreign clipboard change: overwrite instead of append to resync
registers.write('+', vec![value])?;
}
other => other?,
} Prevention
- Prefer a single write over repeated pushes to '*'/'+'.
- Accumulate in named registers; copy to the clipboard once at the end.
- Disable clipboard managers that trim newlines or rewrite contents between yanks.
When it happens
Trigger: Yank/push to the '+' register, copy something in any other application (or let a clipboard manager mutate/normalize it), then push again to the same register; also triggered by clipboard managers that trim trailing newlines or re-encode text.
Common situations: Accumulating multiple selections into the clipboard across a few minutes while using the OS normally; Linux clipboard managers (clipit, klipper) or tmux/Wayland synchronization altering contents; whitespace/newline normalization by desktop environments between pushes.
Related errors
- Register {name} does not support writing
- Register {name} does not support pushing
- Failed to parse snippet. Remaining input: {}
- Command not provided
- Incorrect transport {}
AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16).
Data as JSON: /api/errors/357e3a68813f75d2.
Report an issue: GitHub.