Tencent/tinker · error · Exception

proguard warning must begin with 'Warning:', line=

Error message

proguard warning must begin with 'Warning:', line=

What it means

Raised by RemoveProguardWarning.remove_warning() in tinker-build/tinker-patch-cli/tool_output/proguard_warning.py (line 55) while reading the warning file. This tool consumes proguard's applymapping-conflict warnings ('Warning: ... can't find referenced class ...' style lines), parses them as colon-separated fields, and strips the conflicting entries from the mapping. Every line of the input MUST start with 'Warning:' — anything else (mapping lines, blank-ish content, other proguard stderr like 'Note:' or 'ERROR') fails this check immediately.

Source

Thrown at tinker-build/tinker-patch-cli/tool_output/proguard_warning.py:55

                        self.classes[current_mapping_data.key] = current_mapping_data
                        self.class_list.append(current_mapping_data.key)

                    current_mapping_data = MappingData()
                    current_mapping_data.raw_line = line
                    current_mapping_data.key = line.split('->')[0].strip()
                else:
                    current_mapping_data.filed_methods.append(line)

            self.classes[current_mapping_data.key] = current_mapping_data
            self.class_list.append(current_mapping_data.key)

        # print "size: ", len(self.classes)

    def remove_warning(self, warning):
        with open(warning) as fd:
            for line in fd.readlines():
                if not line.startswith("Warning:"):
                    raise Exception("proguard warning must begin with 'Warning:', line=", line)
                splits = line.split(':')
                class_key = splits[1].strip()
                # print "class_key", class_key
                if class_key not in self.classes:
                    print "Warning:can't find warning class in the mapping file, class=", class_key
                    continue
                warning_value = splits[2].split("'")[1] + " -> " + splits[2].split("'")[5]
                mapping_data = self.classes[class_key]
                # print "warning_value", warning_value

                find = False
                for mappings in mapping_data.filed_methods:
                    if mappings.find(warning_value) != -1:
                        mapping_data.filed_methods.remove(mappings)
                        find = True
                        break

                if not find:

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Pass a warning file containing only proguard 'Warning:' lines: filter first, e.g. grep '^Warning:' proguard-output.txt > warnings.txt.
  2. Double-check argument order — args[0] is the mapping, args[1] is the warnings file.
  3. Reproduce the warnings by building the current version with -applymapping old_mapping.txt and capturing its warning output.
  4. If you maintain the tool, skip non-conforming lines with a logged warning instead of raising, since a mixed log is common.

Example fix

# before
python proguard_warning.py mapping.txt full_build_log.txt

# after
grep '^Warning:' full_build_log.txt > warnings.txt
python proguard_warning.py mapping.txt warnings.txt
Defensive patterns

Strategy: validation

Validate before calling

# keep only genuine warning lines before handing the file to the tool
grep '^Warning:' proguard_output.txt > warnings.txt
python proguard_warning.py mapping.txt warnings.txt

Type guard

def is_warning_file(path):
    with open(path) as f:
        lines = [l for l in f if l.strip()]
    return bool(lines) and all(l.startswith('Warning:') for l in lines)

Try / catch

try:
    RemoveProguardWarning().do_command(args)
except Exception as e:
    if 'must begin with' in str(e):
        sys.exit('warnings file contains non-Warning lines — filter with grep ^Warning: first')
    raise

Prevention

When it happens

Trigger: Running 'python proguard_warning.py mapping.txt warning.txt' where warning.txt is not the captured proguard warning output: mapping.txt passed in the second slot, a combined stderr log containing 'Note:'/'Reading program jar...' lines, an edited file, or a warnings file from a run that never emitted warnings but has a header.

Common situations: Saving proguard's full stderr (which mixes 'Reading...', 'Note:', and 'Warning:' lines) instead of filtering to Warning: lines; swapping the two CLI arguments; regenerating the warning file with a different proguard/R8 version that prefixes lines differently.

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/beee7fa4b5ca08b6. Report an issue: GitHub.