kovidgoyal/kitty · error

Malformed Cursor Position Report from terminal: %s

Error message

Malformed Cursor Position Report from terminal: %s

What it means

The terminal's cursor position report was split on ';' but the first half (the row) is not a valid integer. cpos_from_report uses strconv.Atoi on the row component and fails, meaning the report is malformed even though it contained a separator.

Source

Thrown at tools/cli/wcswidth_kitten.go:32

	"github.com/kovidgoyal/kitty/tools/tui/loop"
	"github.com/kovidgoyal/kitty/tools/utils"
	"github.com/kovidgoyal/kitty/tools/utils/style"
	"github.com/kovidgoyal/kitty/tools/wcswidth"
)

var _ = fmt.Print

type cpos struct {
	x, y int
}

func cpos_from_report(csi string) (ans cpos, err error) {
	before, after, found := strings.Cut(csi, ";")
	if !found {
		return ans, fmt.Errorf("Malformed Cursor Position Report from terminal with no ;")
	}
	if ans.y, err = strconv.Atoi(before); err != nil {
		return ans, fmt.Errorf("Malformed Cursor Position Report from terminal: %s", csi)
	}
	if ans.x, err = strconv.Atoi(after); err != nil {
		return ans, fmt.Errorf("Malformed Cursor Position Report from terminal: %s", csi)
	}
	// convert 1-based indexing to zero based indexing
	ans.x--
	ans.y--
	return
}

type test_struct struct {
	description               string
	num                       int
	expected_cursor_positions []int
	actual_cursor_positions   []cpos
	payload                   string
	tester                    func(actual_cursor_positions []cpos, screen_width int) string
	payload_gen               func(width_in_cells int) string

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Run in a known-conformant terminal without multiplexers
  2. Verify no background process is writing to / reading from the controlling terminal
  3. Update kitty to matching versions on both ends
Defensive patterns

Strategy: validation

Validate before calling

before, _, _ := strings.Cut(csi, ";")
if _, err := strconv.Atoi(before); err != nil { /* skip report */ }

Try / catch

if _, err := cpos_from_report(csi); err != nil { /* discard and re-query cursor position */ }

Prevention

When it happens

Trigger: A CPR response whose row field is non-numeric, e.g. "\x1b[abc;5R", or a truncated/interleaved response where digits were lost or replaced by other escape sequence bytes.

Common situations: Terminal emulators or multiplexers that inject status lines or partial sequences into the input stream, latency/truncation of the tty read, or a non-conformant terminal responding to CSI 6n with unexpected data.

Understand the failure class

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/647155e8f32862ab. Report an issue: GitHub.