ungoogled-software/ungoogled-chromium · error · ValueError
Path "{relative_path}" contains the file index hash delimite
Error message
Path "{relative_path}" contains the file index hash delimiter "{_INDEX_HASH_DELIMITER}" What it means
The file index uses _INDEX_HASH_DELIMITER to separate each path from its hash. apply_substitution() raises ValueError if any relative path in the list contains that delimiter, because the cache file index would become ambiguous. It conveniently removes the partially-written cache tar before raising.
Source
Thrown at utils/domain_substitution.py:218
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()
raise ValueError(f'Path "{relative_path}" contains '
f'the file index hash delimiter "{_INDEX_HASH_DELIMITER}"')
path = resolved_tree / relative_path
if not path.exists():
get_logger().warning('Skipping non-existent path: %s', path)
continue
if path.is_symlink():
get_logger().warning('Skipping path that has become a symlink: %s', path)
continue
with _update_timestamp(path, set_new=True):
crc32_hash, orig_content = _substitute_path(path, regex_pairs)
if crc32_hash is None:
get_logger().info('Path has no substitutions: %s', relative_path)
continue
if domainsub_cache:
fileindex_content.write(
f'{relative_path}{_INDEX_HASH_DELIMITER}{crc32_hash:08x}\n'.encode(ENCODING))
orig_tarinfo = tarfile.TarInfo(str(Path(_ORIG_DIR) / relative_path))
orig_tarinfo.size = len(orig_content)View on GitHub (pinned to f85e84a480)
Solutions
- Fix or regenerate the files list so paths do not contain the delimiter
- Remove/rename the offending entry containing the delimiter
- Escape or strip the delimiter sequence from the path if it is legitimately part of the filename
Example fix
// before
files_txt = 'path' + DELIM + 'hash' # path itself contains DELIM -> ValueError
// after
if any(DELIM in p for p in paths):
raise ValueError('clean paths before building file index')
write_file_index(paths, hashes) Defensive patterns
Strategy: validation
Validate before calling
DELIM = '\n' # whatever _INDEX_HASH_DELIMITER is in your data source
bad = [p for p in file_index_lines if DELIM in p.split(DELIM)[0]]
if bad:
raise ValueError(f'paths contain delimiter: {bad}') Try / catch
try:
apply_substitution(tree, regexes, files)
except ValueError as e:
log.error('Malformed file index entry: %s', e)
raise Prevention
- Never hand-edit the file index; generate it programmatically
- Follow the documented path<delimiter>hash line format
- Validate index lines before passing them to the library
When it happens
Trigger: A line in the files list contains the delimiter string within the path portion — e.g. a malformed/hand-edited file index, or a path that literally contains the delimiter characters.
Common situations: Manually editing or regenerating the file list with the wrong format; hashing tool producing entries in a different delimiter convention; concatenated entries from a bad script.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
AI-assisted analysis of ungoogled-software/ungoogled-chromium@f85e84a480 (2026-08-29).
Data as JSON: /api/errors/f0f57beae972bfdb.
Report an issue: GitHub.