kovidgoyal/kitty · error

Could not encode message to kitty with error: %w

Error message

Could not encode message to kitty with error: %w

What it means

json.Marshal failed to serialize the message being sent to the kitty font backend. This only happens with values Go cannot encode: channels, functions, complex numbers, cyclic data structures, or NaN floats.

Source

Thrown at kittens/choose_fonts/backend.go:73

	}
	k.started = true
	k.timeout = 60 * time.Second
	k.wait_for_exit = make(chan error)
	go func() {
		k.wait_for_exit <- k.cmd.Wait()
	}()
	return
}

var kitty_font_backend kitty_font_backend_type

func (k *kitty_font_backend_type) send(v any) error {
	if k.to == nil {
		return fmt.Errorf("Trying to send data when to pipe is nil")
	}
	data, err := json.Marshal(v)
	if err != nil {
		return fmt.Errorf("Could not encode message to kitty with error: %w", err)
	}
	c := make(chan error)
	go func() {
		if _, err = k.to.Write(data); err != nil {
			c <- fmt.Errorf("Failed to send message to kitty with I/O error: %w", err)
			return
		}
		if _, err = k.to.Write([]byte{'\n'}); err != nil {
			c <- fmt.Errorf("Failed to send message to kitty with I/O error: %w", err)
			return
		}
		c <- nil
	}()
	select {
	case err := <-c:
		return err
	case <-time.After(k.timeout):
		return fmt.Errorf("Timed out waiting to write to kitty font backend after %v", k.timeout)

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Ensure the payload contains only JSON-encodable types (no chan/func/complex/cycles)
  2. Sanitize floats: replace NaN/Inf with math.IsNaN checks before send
  3. Add a unit test that json.Marshals every message type you send

Example fix

// before
backend.send(map[string]any{"v": math.NaN()})
// after
backend.send(map[string]any{"v": 0})
Defensive patterns

Strategy: validation

Validate before calling

if _, err := json.Marshal(v); err != nil { /* reject payload before send */ }

Type guard

func isJSONEncodable(v any) bool { _, err := json.Marshal(v); return err == nil }

Try / catch

Pre-marshal to detect unencodable payloads; on error, sanitize the struct (drop chans/funcs, fix NaN) and retry.

Prevention

When it happens

Trigger: Calling send(v) with v containing a channel, func, NaN/Inf float, or cyclic pointer graph destined for the +runpy backend.

Common situations: Custom forks of choose_fonts passing non-serializable state; floats computed as NaN (0/0) sneaking into font metrics structs.

Related errors


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