kovidgoyal/kitty · error · ValueError

Failed to convert {src_path} to RGBA data with error: {cp.st

Error message

Failed to convert {src_path} to RGBA data with error: {cp.stderr.decode("utf-8", "replace")}

What it means

Image rendering shells out to 'kitten __convert_image__ RGBA'; a non-zero exit code yields ValueError with the subprocess stderr. The source image could not be converted to raw RGBA.

Source

Thrown at kitty/render_cache.py:76

            return 0.0

        entries.sort(key=sort_key, reverse=True)
        for e in entries[self.max_entries :]:
            with suppress(FileNotFoundError):
                os.remove(e.path)

    def touch(self, path: str) -> None:
        os.utime(path, follow_symlinks=False)

    def render_image(self, src_path: str, output_path: str) -> None:
        import stat
        import subprocess

        try:
            with open(src_path, 'rb') as src, open(output_path, 'wb', opener=partial(os.open, mode=stat.S_IREAD | stat.S_IWRITE)) as output:
                cp = subprocess.run([kitten_exe(), '__convert_image__', 'RGBA'], stdin=src, stdout=output, stderr=subprocess.PIPE)
                if cp.returncode != 0:
                    raise ValueError(f'Failed to convert {src_path} to RGBA data with error: {cp.stderr.decode("utf-8", "replace")}')
                if output.seek(0, os.SEEK_END) < 8:
                    raise ValueError(f'Failed to convert {src_path} to RGBA data, no output written. stderr: {cp.stderr.decode("utf-8", "replace")}')
        except Exception:
            with suppress(Exception):
                os.unlink(output_path)
            raise

    def read_metadata(self, output_path: str) -> tuple[int, int, int]:
        with open(output_path, 'rb') as f:
            header = f.read(8)
            import struct

            width, height = struct.unpack('<II', header)
            f.seek(0)
            return width, height, os.dup(f.fileno())

    def render(self, src_path: str) -> str:
        import struct

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Verify the image opens in another tool; re-export it as PNG/JPEG
  2. Check the embedded stderr in the message for the underlying decode error
  3. Regenerate or re-download the source file
Defensive patterns

Strategy: try-catch

Validate before calling

from PIL import Image
with Image.open(src_path) as im: im.verify()  # cheap sanity check

Try / catch

except ValueError as e: log(e); skip/quarantine the image

Prevention

When it happens

Trigger: Passing a corrupt or unsupported image file (bad PNG/JPEG, zero-byte file, unsupported format) to the GPU/emoji render cache pipeline.

Common situations: Caching rendered images for hints/thumbnails when the input file is truncated, corrupt, or an exotic format.

Related errors


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