ungoogled-software/ungoogled-chromium · error · UnicodeDecodeError
Unable to decode with any encoding: {path}
Error message
Unable to decode with any encoding: {path} What it means
_substitute_path() attempts to decode each file with a list of candidate encodings (e.g. UTF-8, then Latin-1). If decoding fails for every encoding, `content` stays unset/empty and a UnicodeDecodeError is raised with this message naming the file.
Source
Thrown at utils/domain_substitution.py:109
"""
if not os.access(path, os.W_OK):
# If the patch cannot be written to, it cannot be opened for updating
print(str(path) + " cannot be opened for writing! Adding write permission...")
path.chmod(path.stat().st_mode | stat.S_IWUSR)
with path.open('r+b') as input_file:
original_content = input_file.read()
if not original_content:
return (None, None)
content = None
encoding = None
for encoding in TREE_ENCODINGS:
try:
content = original_content.decode(encoding)
break
except UnicodeDecodeError:
continue
if not content:
raise UnicodeDecodeError(f'Unable to decode with any encoding: {path}')
file_subs = 0
for regex_pair in regex_iter:
content, sub_count = regex_pair.pattern.subn(regex_pair.replacement, content)
file_subs += sub_count
if file_subs > 0:
substituted_content = content.encode(encoding)
input_file.seek(0)
input_file.write(content.encode(encoding))
input_file.truncate()
return (zlib.crc32(substituted_content), original_content)
return (None, None)
def _validate_file_index(index_file, resolved_tree, cache_index_files):
"""
Validation of file index and hashes against the source tree.
Updates cache_index_files
View on GitHub (pinned to f85e84a480)
Solutions
- Remove the offending path from the file list (files list) used by apply_substitution()
- Add the file's actual encoding to the encoding list used for decoding
- Re-obtain the file — it may be corrupted or truncated
- If the file should be binary, exclude it from domain substitution
Example fix
# before: binary file in substitution list
domsub_apply(source_tree, regexes, files_list)
# after: filter binary files out first
files = [f for f in files_list if not (source_tree / f).suffix in {'.png', '.webp', '.wasm'}]
domsub_apply(source_tree, regexes, files) Defensive patterns
Strategy: try-catch
Validate before calling
for f in file_list:
data = (source_tree / f).read_bytes()
if b'\x00' in data[:1024]:
raise ValueError(f'binary file in substitution list: {f}') Try / catch
try:
apply_substitution(tree, regexes, files)
except UnicodeDecodeError as e:
log.error('Undecodable file, exclude it from the substitution list: %s', e)
raise Prevention
- Exclude binary file types from the substitution file list
- Ensure files are saved in an encoding included in the decoding list
- Re-download corrupted files instead of substituting them
When it happens
Trigger: apply_substitution() iterating the file index reaches a file whose bytes are not valid in any of the configured encodings — a binary file or a file in an unsupported encoding matched by the regex list.
Common situations: Binary resources (images, webp, wasm) ending up in the domain-substitution file list; files saved in UTF-16 or another encoding not in the ENCODING_LIST; corrupted downloads.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of ungoogled-software/ungoogled-chromium@f85e84a480 (2026-08-29).
Data as JSON: /api/errors/156c95e64dd658bd.
Report an issue: GitHub.