kovidgoyal/kitty · error

Failed to read data from image output data file: %w

Error message

Failed to read data from image output data file: %w

What it means

io.ReadFull failed while copying the frame file's bytes into the shared-memory segment — fewer bytes were available than the earlier size determination promised, or a read error occurred.

Source

Thrown at kittens/icat/transmit.go:106

	if frame.in_memory_bytes == nil {
		f, err := os.Open(frame.filename)
		if err != nil {
			return fmt.Errorf("Failed to open image data output file: %s with error: %w", frame.filename, err)
		}
		defer f.Close()
		if data_size, err = f.Seek(0, io.SeekEnd); err != nil {
			return fmt.Errorf("Failed to seek in image data output file: %s with error: %w", frame.filename, err)
		}
		if _, err = f.Seek(0, io.SeekStart); err != nil {
			return fmt.Errorf("Failed to seek in image data output file: %s with error: %w", frame.filename, err)
		}
		if mmap, err = shm.CreateTemp("icat-*", uint64(data_size)); err != nil {
			return fmt.Errorf("Failed to create a SHM file for transmission: %w", err)
		}
		if _, err = io.ReadFull(f, mmap.Slice()); err != nil {
			mmap.Close()
			mmap.Unlink()
			return fmt.Errorf("Failed to read data from image output data file: %w", err)
		}
	} else {
		data_size = int64(len(frame.in_memory_bytes))
		if mmap, err = shm.CreateTemp("icat-*", uint64(data_size)); err != nil {
			return fmt.Errorf("Failed to create a SHM file for transmission: %w", err)
		}
		copy(mmap.Slice(), frame.in_memory_bytes)
	}
	defer mmap.Close() // terminal is responsible for unlink
	gc := gc_for_image(imgd, frame_num, frame)
	gc.SetTransmission(graphics.GRT_transmission_sharedmem)
	gc.SetDataSize(uint64(data_size))
	err = gc.WriteWithPayloadTo(os.Stdout, utils.UnsafeStringToBytes(mmap.Name()))
	return
}

func transmit_file(imgd *image_data, frame_num int, frame *image_frame) (err error) {
	is_temp := false

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Retry the icat run
  2. Point TMPDIR at stable local storage
  3. Avoid running concurrent icat instances over the same temp files
Defensive patterns

Strategy: retry

Validate before calling

fi, _ := os.Stat(f)
// verify size unchanged between sizing and reading before transmit

Try / catch

if err != nil && strings.Contains(err.Error(), "Failed to read data") { /* regenerate frame and retry once */ }

Prevention

When it happens

Trigger: File truncated between Seek (size) and ReadFull, or an I/O error mid-read from disk/NFS.

Common situations: Concurrent truncation of temp files; flaky network filesystems hosting TMPDIR; race with cleanup processes.

Related errors


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