{"record":{"id":"beee7fa4b5ca08b6","repo":"Tencent/tinker","slug":"proguard-warning-must-begin-with-warning-line","errorCode":null,"errorMessage":"proguard warning must begin with 'Warning:', line=","messagePattern":"proguard warning must begin with 'Warning:', line=","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"tinker-build/tinker-patch-cli/tool_output/proguard_warning.py","lineNumber":55,"sourceCode":"                        self.classes[current_mapping_data.key] = current_mapping_data\n                        self.class_list.append(current_mapping_data.key)\n\n                    current_mapping_data = MappingData()\n                    current_mapping_data.raw_line = line\n                    current_mapping_data.key = line.split('->')[0].strip()\n                else:\n                    current_mapping_data.filed_methods.append(line)\n\n            self.classes[current_mapping_data.key] = current_mapping_data\n            self.class_list.append(current_mapping_data.key)\n\n        # print \"size: \", len(self.classes)\n\n    def remove_warning(self, warning):\n        with open(warning) as fd:\n            for line in fd.readlines():\n                if not line.startswith(\"Warning:\"):\n                    raise Exception(\"proguard warning must begin with 'Warning:', line=\", line)\n                splits = line.split(':')\n                class_key = splits[1].strip()\n                # print \"class_key\", class_key\n                if class_key not in self.classes:\n                    print \"Warning:can't find warning class in the mapping file, class=\", class_key\n                    continue\n                warning_value = splits[2].split(\"'\")[1] + \" -> \" + splits[2].split(\"'\")[5]\n                mapping_data = self.classes[class_key]\n                # print \"warning_value\", warning_value\n\n                find = False\n                for mappings in mapping_data.filed_methods:\n                    if mappings.find(warning_value) != -1:\n                        mapping_data.filed_methods.remove(mappings)\n                        find = True\n                        break\n\n                if not find:","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-build/tinker-patch-cli/tool_output/proguard_warning.py#L37-L73","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass a warning file containing only proguard 'Warning:' lines: filter first, e.g. grep '^Warning:' proguard-output.txt > warnings.txt.","Double-check argument order — args[0] is the mapping, args[1] is the warnings file.","Reproduce the warnings by building the current version with -applymapping old_mapping.txt and capturing its warning output.","If you maintain the tool, skip non-conforming lines with a logged warning instead of raising, since a mixed log is common."],"exampleFix":"# before\npython proguard_warning.py mapping.txt full_build_log.txt\n\n# after\ngrep '^Warning:' full_build_log.txt > warnings.txt\npython proguard_warning.py mapping.txt warnings.txt","handlingStrategy":"validation","validationCode":"# keep only genuine warning lines before handing the file to the tool\ngrep '^Warning:' proguard_output.txt > warnings.txt\npython proguard_warning.py mapping.txt warnings.txt","typeGuard":"def is_warning_file(path):\n    with open(path) as f:\n        lines = [l for l in f if l.strip()]\n    return bool(lines) and all(l.startswith('Warning:') for l in lines)","tryCatchPattern":"try:\n    RemoveProguardWarning().do_command(args)\nexcept Exception as e:\n    if 'must begin with' in str(e):\n        sys.exit('warnings file contains non-Warning lines — filter with grep ^Warning: first')\n    raise","preventionTips":["Filter proguard stderr to lines starting with 'Warning:' before saving the file.","Pass arguments in the documented order: mapping first, warnings second.","Never feed combined build logs or Note:/Reading lines to this tool."],"tags":["python","proguard","warnings","cli","parsing"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}