helix-editor/helix · error · anyhow::Error

Register {name} does not support pushing

Error message

Register {name} does not support pushing

What it means

Registers::push appends to a register and has the same read-only guard as write: pushing to '#', '.', or '%' fails with "Register {name} does not support pushing". The black-hole '_' accepts pushes and ignores them.

Source

Thrown at helix-view/src/register.rs:108

                        _ => unreachable!(),
                    },
                )?;
                values.reverse();
                self.inner.insert(name, values);
                Ok(())
            }
            _ => {
                values.reverse();
                self.inner.insert(name, values);
                Ok(())
            }
        }
    }

    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() {

View on GitHub (pinned to 079a789e8c)

Solutions

  1. Append to a named register (e.g. 'a' via its append form) or to the clipboard registers '*'/'+'.
  2. If you meant to accumulate clipboard content, use '+' with push — but note the clipboard-consistency check that push applies.
  3. Treat '#', '.', '%' as read-only displays of editor state.

Example fix

# before
 :set-register . "text"  / append to '.'

# after
 accumulate into a named register, e.g. append to "a"
Defensive patterns

Strategy: validation

Validate before calling

const READ_ONLY_REGISTERS: [char; 3] = ['#', '.', '%'];

fn can_push_register(name: char) -> bool {
    !READ_ONLY_REGISTERS.contains(&name)
}

if !can_push_register(name) {
    return Err(anyhow!("register '{name}' is read-only; append to a named register instead"));
}

Type guard

fn pushable_register(name: char) -> Option<char> {
    (!matches!(name, '#' | '.' | '%')).then_some(name)
}

Try / catch

match registers.push(name, value) {
    Err(err) if err.to_string().contains("does not support pushing") => {
        registers.push('a', value)?; // fall back to a named accumulator
    }
    other => other?,
}

Prevention

When it happens

Trigger: An append-style yank (capital register usage or an append command) targeting '%', '.', or '#'; calling registers.push('.', s) from code.

Common situations: Accumulating multiple yanks into the last-inserted-text or filename register by mistake; muscle memory from appending to letter registers applied to a special register.

Related errors


AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16). Data as JSON: /api/errors/d9998614c462df10. Report an issue: GitHub.