Embedded sidecars cache file handles and go stale
Diagnosing why an audiobook reader returned HTTP 500 immediately after a successful alignment pipeline finished writing a new aligned epub
Self-hosted apps that bundle a sidecar process for asset serving (like storyteller bundling Readium-go-toolkit for epub reading) will cache open file handles on the assets. If the main apps worker process rewrites those assets while the sidecar still has the handle open, the sidecar sees an inconsistent file state and starts returning HTTP 500 errors like resource: error 500: zip: not a valid zip file — even though the file on disk is now perfectly valid (Python zipfile.testzip passes, the file is the full final size). The handle is stale, frozen at a snapshot from mid-write. The mitigation is a docker restart of the host container after any pipeline stage that rewrites a served asset. This applies broadly: any embedded sidecar (Readium for ebooks, llama.cpp for LLM weights, Tesseract for OCR caches, image-resize daemons) that opens files lazily will exhibit this pattern. Either the app invalidates handles on filesystem change (rare in practice) or you bake a post-rewrite restart into your pipeline.
When a self-hosted app starts returning 500s right after a successful pipeline run that wrote new files, first verify the files on disk are valid (python -c "import zipfile; zipfile.ZipFile(p).testzip()" or analogous). If they are valid, the issue is almost certainly a stale sidecar handle — docker restart the container before doing any other debugging. Add this restart step to any documented pipeline that involves rewriting served assets.