{"record":{"id":"859c7dcbb701595c","repo":"kubernetes/kubernetes","slug":"filtering-incompatible-changes-w","errorCode":null,"errorMessage":"filtering incompatible changes: %w","messagePattern":"filtering incompatible changes: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hack/apidiff-changelog/main.go","lineNumber":500,"sourceCode":"\tfiltered = trimTrailingEmpty(filtered)\n\n\tfmt.Printf(\"## %s\\n\", what)\n\tif len(filtered) == 0 {\n\t\tfmt.Println(\"no changes\")\n\t\treturn \"\", nil\n\t}\n\n\tpreamble, incompatibleLines, compatibleLines := splitApidiffSections(filtered)\n\n\t// Filter incompatible changes through the allowlist.\n\tincompatibleStr := strings.Join(incompatibleLines, \"\\n\")\n\ttolerated, err := filterChanges(incompatibleStr, false)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"filtering tolerated changes: %w\", err)\n\t}\n\tincompatibleStr, err = filterChanges(incompatibleStr, true)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"filtering incompatible changes: %w\", err)\n\t}\n\n\t// Print preamble (matches shell's `echo \"$changes\"`, even when empty, producing a blank line).\n\tfmt.Println(preamble)\n\tif incompatibleStr != \"\" {\n\t\tfmt.Println(\"Incompatible changes:\")\n\t\tfmt.Print(incompatibleStr)\n\t}\n\tif tolerated != \"\" {\n\t\tfmt.Println(\"Acceptable incompatible changes:\")\n\t\tfmt.Print(tolerated)\n\t}\n\tif len(compatibleLines) > 0 {\n\t\tfmt.Println(\"Compatible changes:\")\n\t\tfmt.Println(strings.Join(compatibleLines, \"\\n\"))\n\t}\n\tfmt.Println()\n","sourceCodeStart":482,"sourceCodeEnd":518,"githubUrl":"https://github.com/kubernetes/kubernetes/blob/b882c60b4023bdf09264c2d5d30a2cadebc240fb/hack/apidiff-changelog/main.go#L482-L518","documentation":"Wrapped error from filterChanges when compiling the allowlist to extract the 'incompatible' (non-allowlisted) changes (main.go:498-500). This is the second filterChanges call (exclude=true). It uses the identical compileAllowlistPatterns path as error 457, so the root cause is the same: a malformed regex in the embedded allowlist.","triggerScenarios":"Same as 457 — compileAllowlistPatterns fails. In practice if error 457 fires it fires first (it is called first at main.go:494), so this branch is only reached if compileAllowlistPatterns becomes non-deterministic, which it is not. Treat both as the same class of defect.","commonSituations":"Identical to error 457: invalid regex in api-changes-allowlist. In the current code ordering, error 457 will surface before this one; 458 is effectively defensive/unreachable given a single bad line.","solutions":["Same as 457 — fix the invalid regex in api-changes-allowlist.","Run `go test ./hack/apidiff-changelog/...` to catch the regression before it ships.","Add a unit test that asserts compileAllowlistPatterns returns no error, to prevent recurrence."],"exampleFix":"// before: bad regex line in api-changes-allowlist\n^*invalid(\n// filtering incompatible changes: failed to compile regex \"^*invalid(\": error parsing regexp...\n\n// after\n^[a-z]+: (added|removed)$\n// plus a guard test:\nfunc TestAllowlistCompiles(t *testing.T) { if _, err := compileAllowlistPatterns(); err != nil { t.Fatal(err) } }","handlingStrategy":"validation","validationCode":"// Same guard as 457 — a single test covers both filterChanges invocations.\nfunc TestAllowlistCompiles(t *testing.T) {\n    if _, err := compileAllowlistPatterns(); err != nil { t.Fatalf(\"allowlist: %v\", err) }\n}","typeGuard":"null","tryCatchPattern":"incompatibleStr, err = filterChanges(incompatibleStr, true)\nif err != nil { return \"\", fmt.Errorf(\"filtering incompatible changes: %w\", err) }","preventionTips":["Treat 457 and 458 as the same defect class — fix the allowlist once.","Add the compile guard test to prevent either from recurring.","Review allowlist PRs for RE2 compatibility."],"tags":["go","kubernetes","regex","allowlist","embedded","apidiff"],"analyzedSha":"b882c60b4023bdf09264c2d5d30a2cadebc240fb","analyzedAt":"2026-08-07T04:07:48.144Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}