{"record":{"id":"4b2367212375498e","repo":"ungoogled-software/ungoogled-chromium","slug":"filenotfounderror","errorCode":null,"errorMessage":"FileNotFoundError","messagePattern":"FileNotFoundError","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"utils/domain_substitution.py","lineNumber":199,"sourceCode":"\ndef apply_substitution(regex_path, files_path, source_tree, domainsub_cache):\n    \"\"\"\n    Substitute domains in source_tree with files and substitutions,\n        and save the pre-domain substitution archive to presubdom_archive.\n\n    regex_path is a pathlib.Path to domain_regex.list\n    files_path is a pathlib.Path to domain_substitution.list\n    source_tree is a pathlib.Path to the source tree.\n    domainsub_cache is a pathlib.Path to the domain substitution cache.\n\n    Raises NotADirectoryError if the patches directory is not a directory or does not exist\n    Raises FileNotFoundError if the source tree or required directory does not exist.\n    Raises FileExistsError if the domain substitution cache already exists.\n    Raises ValueError if an entry in the domain substitution list contains the file index\n        hash delimiter.\n    \"\"\"\n    if not source_tree.exists():\n        raise FileNotFoundError(source_tree)\n    if not regex_path.exists():\n        raise FileNotFoundError(regex_path)\n    if not files_path.exists():\n        raise FileNotFoundError(files_path)\n    if domainsub_cache and domainsub_cache.exists():\n        raise FileExistsError(domainsub_cache)\n    resolved_tree = source_tree.resolve()\n    regex_pairs = DomainRegexList(regex_path).regex_pairs\n    fileindex_content = io.BytesIO()\n    with tarfile.open(str(domainsub_cache), f'w:{domainsub_cache.suffix[1:]}',\n                      compresslevel=1) if domainsub_cache else open(\n                          os.devnull, 'w', encoding=ENCODING) as cache_tar:\n        for relative_path in filter(len, files_path.read_text().splitlines()):\n            if _INDEX_HASH_DELIMITER in relative_path:\n                if domainsub_cache:\n                    # Cache tar will be incomplete; remove it for convenience\n                    cache_tar.close()\n                    domainsub_cache.unlink()","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/ungoogled-software/ungoogled-chromium/blob/f85e84a480e2e17c103de7013de94320f9a2ba39/utils/domain_substitution.py#L181-L217","documentation":"apply_substitution() validates its inputs before doing any work. It raises FileNotFoundError(source_tree) when the given source tree directory does not exist on disk, as documented in its docstring.","triggerScenarios":"Calling apply_substitution(source_tree=..., regex_path=..., files_path=...) with a source_tree Path that fails .exists() — a typo'd path, a path relative to the wrong working directory, or a tree deleted before the call.","commonSituations":"Running the callback from a different CWD than expected (relative paths not resolving); typo in the unpacked tree location; extraction step skipped/failed so the tree was never created.","solutions":["Pass an absolute, existing directory as source_tree (Path(...).resolve() and verify it exists)","Create/extract the source tree before calling apply_substitution()","Fix the CWD (os.chdir or absolute paths) if relying on relative paths"],"exampleFix":"// before\napply_substitution(Path('build/chromium_src'), regexes, files)\n// after\ntree = Path('build/chromium_src').resolve()\nif not tree.is_dir():\n    raise NotADirectoryError(tree)\napply_substitution(tree, regexes, files)","handlingStrategy":"validation","validationCode":"tree = Path(source_tree).resolve()\nif not tree.is_dir():\n    raise NotADirectoryError(f'source_tree does not exist: {tree}')","typeGuard":null,"tryCatchPattern":"try:\n    apply_substitution(tree, regexes, files)\nexcept FileNotFoundError as e:\n    log.error('Missing input path: %s', e)\n    raise","preventionTips":["Always pass resolved absolute paths","Ensure the extraction step completed before substitution","Avoid depending on the current working directory"],"tags":["filesystem","missing-path","substitution"],"backgroundTag":"file-not-found","analyzedSha":"f85e84a480e2e17c103de7013de94320f9a2ba39","analyzedAt":"2026-08-29T10:07:17.606Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}