Skip to content

Bug: undo crashes with "Invalid line number" and fails validation on :Opencode undo #249

@baroque-cat

Description

@baroque-cat

Environment

  • OS: Arch Linux
  • Neovim configuration: LazyVim
  • Plugin: opencode.nvim

Description

I encountered two related issues when using the undo functionality.

1. Command Line (:Opencode undo) - Validation Error

When executing :Opencode undo, the backend returns an invalid_type error because the command arguments are passed as a table (array) instead of a string.

Error Log:

  Error  03:54:09 PM notify.error Failed to undo last message: {
  data = {
    messageID = {}
  },
  error = { {
      code = "invalid_type",
      expected = "string",
      message = "Invalid input: expected string, received array",
      path = { "messageID" }
    } },
  success = false
}

2. Slash Command (/undo) - Rendering Crash

When using /undo, the action initially seems to work, but sending a new message triggers a crash in the renderer. This causes the "undone" message to reappear due to the UI failing to clear the extmarks correctly.

Error Log:

   Error  03:53:49 PM notify.error Error calling message.removed listener: ...vim/lazy/opencode.nvim/lua/opencode/ui/output_window.lua:174: Invalid line number: out of range
stack traceback:
	...vim/lazy/opencode.nvim/lua/opencode/ui/output_window.lua:174: in function 'clear_extmarks'
	...are/nvim/lazy/opencode.nvim/lua/opencode/ui/renderer.lua:551: in function '_remove_message_from_buffer'
	...are/nvim/lazy/opencode.nvim/lua/opencode/ui/renderer.lua:820: in function <...are/nvim/lazy/opencode.nvim/lua/opencode/ui/renderer.lua:798>
	[C]: in function 'pcall_trace'
	...e/nvim/lazy/opencode.nvim/lua/opencode/event_manager.lua:317: in function 'emit'
	...e/nvim/lazy/opencode.nvim/lua/opencode/event_manager.lua:296: in function '_on_drained_events'
	...e/nvim/lazy/opencode.nvim/lua/opencode/event_manager.lua:175: in function 'process_fn'
	...m/lazy/opencode.nvim/lua/opencode/throttling_emitter.lua:49: in function '_drain'
	...m/lazy/opencode.nvim/lua/opencode/throttling_emitter.lua:37: in function ''
	vim/_editor.lua: in function ''
	vim/_editor.lua: in function <vim/_editor.lua:0>

Root Cause Analysis

1.  lua/opencode/api.lua
In M.undo(messageId), the function receives a table when called via user command (because route_command passes arguments as a list). It needs to check if messageId is a table and extract the first element or handle it as nil.

2.  lua/opencode/ui/renderer.lua
The crash occurs in _remove_message_from_buffer (and likely _remove_part_from_buffer).
The code attempts to clear extmarks starting at cached.line_start - 1. If the message starts at line 0 (top of buffer), this evaluates to -1, which is an invalid start line for nvim_buf_clear_namespace.

Affected lines (approximate):

  • renderer.lua:533: output_window.clear_extmarks(cached.line_start - 1, ...)
  • renderer.lua:551: output_window.clear_extmarks(cached.line_start - 1, ...)

Suggested Fix:
Ensure the start line is never negative using math.max(0, cached.line_start - 1).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions