{"record":{"id":"cc93c504c15efbd0","repo":"ocrmypdf/OCRmyPDF","slug":"sidecar-file-must-be-different-from-the-input-an","errorCode":null,"errorMessage":"--sidecar file must be different from the input and output files","messagePattern":"--sidecar file must be different from the input and output files","errorType":"validation","errorClass":"BadArgsError","httpStatus":null,"severity":"error","filePath":"src/ocrmypdf/_validation.py","lineNumber":107,"sourceCode":"def check_options_sidecar(options: OcrOptions) -> None:\n    if options.sidecar == '\\0':\n        if options.output_file == '-':\n            raise BadArgsError(\"--sidecar filename needed when output file is stdout.\")\n        elif options.output_file == os.devnull:\n            raise BadArgsError(\n                \"--sidecar filename needed when output file is /dev/null or NUL.\"\n            )\n        elif not isinstance(options.output_file, str | Path):\n            # The '\\0' sentinel is only ever set by the CLI, which always\n            # supplies output_file as a plain path - not a stream. If this\n            # somehow fires, the caller mixed a CLI-only sentinel with the\n            # stream-based API.\n            raise BadArgsError(\n                \"--sidecar filename needed when output file is not a path.\"\n            )\n        options.sidecar = os.fspath(options.output_file) + '.txt'\n    if options.sidecar == options.input_file or options.sidecar == options.output_file:\n        raise BadArgsError(\n            \"--sidecar file must be different from the input and output files\"\n        )\n\n\ndef check_options_preprocessing(options: OcrOptions) -> None:\n    if options.clean_final:\n        options.clean = True\n    if options.unpaper_args and not options.clean:\n        raise BadArgsError(\"--clean is required for --unpaper-args\")\n    if (\n        options.rotate_pages_threshold != DEFAULT_ROTATE_PAGES_THRESHOLD\n        and not options.rotate_pages\n    ):\n        raise BadArgsError(\"--rotate-pages is required for --rotate-pages-threshold\")\n    if options.clean:\n        check_external_program(\n            program='unpaper',\n            package='unpaper',","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/ocrmypdf/OCRmyPDF/blob/5074a0b0e109362422b768fd271ed84bf717c4ec/src/ocrmypdf/_validation.py#L89-L125","documentation":"Raised when the --sidecar file path equals the input or output file path, which would clobber one of those files when the text sidecar is written.","triggerScenarios":"options.sidecar resolving to the same path as options.input_file or options.output_file (string equality after fsync comparison); checked in check_options_sidecar.","commonSituations":"Auto-derived sidecar colliding with output name (e.g. output 'out.pdf.txt' vs explicit same path); explicitly passing --sidecar in.pdf by mistake.","solutions":["Choose a distinct sidecar filename","Rely on the default derived name (output + '.txt') when possible"],"exampleFix":"# before\nocrmypdf --sidecar in.pdf in.pdf out.pdf\n# after\nocrmypdf --sidecar out.txt in.pdf out.pdf","handlingStrategy":"validation","validationCode":"import os\nif sidecar and os.fspath(sidecar) in (os.fspath(input_file), os.fspath(output_file)):\n    sidecar = str(output_file) + '.txt'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Let ocrmypdf derive the sidecar name (output + '.txt') instead of hand-picking paths"],"tags":["ocr","ocrmypdf","sidecar","file-paths"],"backgroundTag":"path-conflict","analyzedSha":"5074a0b0e109362422b768fd271ed84bf717c4ec","analyzedAt":"2026-08-27T11:57:38.523Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}