ungoogled-software/ungoogled-chromium · error · FileNotFoundError

FileNotFoundError

Error message

FileNotFoundError

What it means

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.

Source

Thrown at utils/domain_substitution.py:199

def apply_substitution(regex_path, files_path, source_tree, domainsub_cache):
    """
    Substitute domains in source_tree with files and substitutions,
        and save the pre-domain substitution archive to presubdom_archive.

    regex_path is a pathlib.Path to domain_regex.list
    files_path is a pathlib.Path to domain_substitution.list
    source_tree is a pathlib.Path to the source tree.
    domainsub_cache is a pathlib.Path to the domain substitution cache.

    Raises NotADirectoryError if the patches directory is not a directory or does not exist
    Raises FileNotFoundError if the source tree or required directory does not exist.
    Raises FileExistsError if the domain substitution cache already exists.
    Raises ValueError if an entry in the domain substitution list contains the file index
        hash delimiter.
    """
    if not source_tree.exists():
        raise FileNotFoundError(source_tree)
    if not regex_path.exists():
        raise FileNotFoundError(regex_path)
    if not files_path.exists():
        raise FileNotFoundError(files_path)
    if domainsub_cache and domainsub_cache.exists():
        raise FileExistsError(domainsub_cache)
    resolved_tree = source_tree.resolve()
    regex_pairs = DomainRegexList(regex_path).regex_pairs
    fileindex_content = io.BytesIO()
    with tarfile.open(str(domainsub_cache), f'w:{domainsub_cache.suffix[1:]}',
                      compresslevel=1) if domainsub_cache else open(
                          os.devnull, 'w', encoding=ENCODING) as cache_tar:
        for relative_path in filter(len, files_path.read_text().splitlines()):
            if _INDEX_HASH_DELIMITER in relative_path:
                if domainsub_cache:
                    # Cache tar will be incomplete; remove it for convenience
                    cache_tar.close()
                    domainsub_cache.unlink()

View on GitHub (pinned to f85e84a480)

Solutions

  1. Pass an absolute, existing directory as source_tree (Path(...).resolve() and verify it exists)
  2. Create/extract the source tree before calling apply_substitution()
  3. Fix the CWD (os.chdir or absolute paths) if relying on relative paths

Example fix

// before
apply_substitution(Path('build/chromium_src'), regexes, files)
// after
tree = Path('build/chromium_src').resolve()
if not tree.is_dir():
    raise NotADirectoryError(tree)
apply_substitution(tree, regexes, files)
Defensive patterns

Strategy: validation

Validate before calling

tree = Path(source_tree).resolve()
if not tree.is_dir():
    raise NotADirectoryError(f'source_tree does not exist: {tree}')

Try / catch

try:
    apply_substitution(tree, regexes, files)
except FileNotFoundError as e:
    log.error('Missing input path: %s', e)
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of ungoogled-software/ungoogled-chromium@f85e84a480 (2026-08-29). Data as JSON: /api/errors/4b2367212375498e. Report an issue: GitHub.