{"record":{"id":"76f509893f57be7f","repo":"ocrmypdf/OCRmyPDF","slug":"a-worker-process-lost-access-to-an-input-file-76f509","errorCode":null,"errorMessage":"A worker process lost access to an input file","messagePattern":"A worker process lost access to an input file","errorType":"error_code","errorClass":"InputFileError","httpStatus":null,"severity":"critical","filePath":"src/ocrmypdf/extra_plugins/semfree.py","lineNumber":67,"sourceCode":"    result = auto()  # pylint: disable=invalid-name\n    complete = auto()  # pylint: disable=invalid-name\n\n\ndef split_every(n: int, iterable: Iterable) -> Iterator:\n    \"\"\"Split iterable into groups of n.\n\n    >>> list(split_every(4, range(10)))\n    [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]\n\n    https://stackoverflow.com/a/22919323\n    \"\"\"\n    iterator = iter(iterable)\n    return takewhile(bool, (list(islice(iterator, n)) for _ in repeat(None)))\n\n\ndef process_sigbus(*args):\n    \"\"\"Handle SIGBUS signal at the worker level.\"\"\"\n    raise InputFileError(\"A worker process lost access to an input file\")\n\n\nclass ConnectionLogHandler(logging.handlers.QueueHandler):\n    \"\"\"Handler used by child processes to forward log messages to parent.\"\"\"\n\n    def __init__(self, conn: Connection) -> None:\n        \"\"\"Initialize the handler.\"\"\"\n        # sets the parent's queue to None - parent only touches queue\n        # in enqueue() which we override\n        super().__init__(None)  # type: ignore\n        self.conn = conn\n\n    def enqueue(self, record):\n        \"\"\"Enqueue a log message.\"\"\"\n        self.conn.send(('log', record))\n\n\ndef process_loop(","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/ocrmypdf/OCRmyPDF/blob/5074a0b0e109362422b768fd271ed84bf717c4ec/src/ocrmypdf/extra_plugins/semfree.py#L49-L85","documentation":"This is the semaphore-free executor plugin's (extra_plugins.semfree) copy of the SIGBUS worker handler: it raises InputFileError when a worker process receives SIGBUS, meaning a mapped/open input or temp file vanished or its storage failed mid-run.","triggerScenarios":"Using the semfree concurrency plugin when an input/temp file is truncated or deleted during processing, or when the filesystem backing it (disk, tmpfs, network mount) errors.","commonSituations":"Same as the builtin pool: tmpfs filling up, aggressive tmp cleaners, or unstable network-mounted inputs, plus choosing semfree for very high page counts.","solutions":["Free space on TMPDIR/output filesystems and retry.","Keep inputs on stable local storage and prevent concurrent deletion/cleanup during the job.","Set TMPDIR to a disk-backed path with enough room."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import shutil, os\nassert shutil.disk_usage(os.environ.get('TMPDIR','/tmp')).free > 1_000_000_000","typeGuard":null,"tryCatchPattern":"from ocrmypdf.exceptions import InputFileError\ntry:\n    run_with_semfree(...)\nexcept InputFileError:\n    stabilize_storage(); retry_job()","preventionTips":["Guard TMPDIR free space with a preflight check.","Avoid network-mounted inputs with the semfree executor."],"tags":["ocrmypdf","semfree","sigbus","multiprocessing","disk-full"],"backgroundTag":"sigbus-input-file-lost","analyzedSha":"5074a0b0e109362422b768fd271ed84bf717c4ec","analyzedAt":"2026-08-27T11:57:38.523Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}