Skip to content

serve: temporary image remains when vision encoder pipe raises #352

Closed

Description

@Tsury

This was generated by AI during triage.

Failure

In v0.1.31 (9259cad4cfa3543cd3b8decab5962672b968c649), Vision.encode() writes a temporary .img file, then writes/flushes the encoder pipe and reads its reply. The img.unlink() call is after those operations.

If the encoder pipe raises (for example, BrokenPipeError after the encoder exits), that image remains in the server's vision temporary directory. The request raises, but cleanup is skipped. Repeated failures on different images can retain additional image copies while the server stays alive.

Reproducer

Run in the checkout's Python environment. No model, GPU or encoder process is needed. The synthetic bytes only exercise I/O cleanup; they are never decoded.

import io
import tempfile
import threading
from pathlib import Path
from types import SimpleNamespace
from serve.server import Vision

def fail_write(_):
    raise BrokenPipeError("synthetic encoder pipe failure")

with tempfile.TemporaryDirectory() as temp:
    vision = Vision.__new__(Vision)
    vision.dir = Path(temp)
    vision.lock = threading.Lock()
    vision.cache = {}
    vision.proc = SimpleNamespace(
        stdin=SimpleNamespace(write=fail_write, flush=lambda: None),
        stdout=io.StringIO(),
    )
    vision.load = lambda _: b"\x89PNG\r\n\x1a\n"
    try:
        vision.encode("synthetic")
    except BrokenPipeError:
        pass
    print(list(Path(temp).glob("*.img")))  # currently one retained file

Confirmed against the exact v0.1.31 Vision class extracted from serve/server.py (source SHA256 d8ab9bb83001123165c14beb46b034ff33bce156957d0241d676aec0ea5407a4). Original exception: BrokenPipeError; remaining .img files: 1.

Expected / narrow repair

Remove the temporary input image even when pipe write, flush or read raises, while preserving the original exception. Put the pipe exchange inside try/finally, with img.unlink(missing_ok=True) in finally. Cache only successful embeddings as before.

Our local repair uses that cleanup. This report does not claim to fix encoder restart/recovery, and does not require an inference-policy or sampling change.

Activity

  1. Niko1221 commented on Oct 1, 2026

    @Niko1221
    Owner

    Thanks! Fixed for the next release: the temporary image is removed in a finally, with a test for a pipe that fails. This issue closes with the release.

  2. added a commit that references this issue on Oct 1, 2026
  3. added a commit that references this issue on Oct 1, 2026
    a1eb951
  4. Niko1221 commented on Oct 1, 2026

    @Niko1221
    Owner

    Fixed in 0.1.33. Thanks!

  5. added 2 commits that reference this issue on Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions