{"record":{"id":"8bbc4dea892f0073","repo":"apache/kafka","slug":"release-version-is-not-complete-since-there-are","errorCode":null,"errorMessage":"\nRelease {version} is not complete since there are unresolved or improperly\nresolved issues tagged {version} as the fix version:\n\n{issue_list}\n\nNote that for some resolutions, you should simply remove the fix version\nas they have not been truly fixed in this release.\n        ","messagePattern":"\nRelease (.+?) is not complete since there are unresolved or improperly\nresolved issues tagged (.+?) as the fix version:\n\n(.+?)\n\nNote that for some resolutions, you should simply remove the fix version\nas they have not been truly fixed in this release\\.\n        ","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"release/notes.py","lineNumber":152,"sourceCode":"    \"\"\"\n    key = \"%15s\" % issue.key\n    resolution = \"%15s\" % issue.fields.resolution\n    link = issue_link(issue)\n    return f\"{key} {resolution} {link}\"\n\ndef generate(version):\n    \"\"\"\n    Generates the release notes in HTML format for given version.\n    Raises an error if there are unresolved issues or no issues\n    at all for the specified version.\n    \"\"\"\n    issues = query(f\"project=KAFKA and fixVersion={version}\")\n    if not issues:\n        raise Exception(f\"Didn't find any issues for version {version}\")\n    unresolved_issues = filter_unresolved(issues)\n    if unresolved_issues:\n        issue_list = \"\\n\".join([issue_str(issue) for issue in unresolved_issues])\n        raise Exception(f\"\"\"\nRelease {version} is not complete since there are unresolved or improperly\nresolved issues tagged {version} as the fix version:\n\n{issue_list}\n\nNote that for some resolutions, you should simply remove the fix version\nas they have not been truly fixed in this release.\n        \"\"\")\n    return render(version, issues)\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 2:\n        print(\"Usage: python notes.py <version>\", file=sys.stderr)\n        sys.exit(1)\n\n    version = sys.argv[1]\n    try:","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/release/notes.py#L134-L170","documentation":"Thrown by the Apache Kafka release-notes generator (release/notes.py) when JIRA issues tagged with the target version as their fixVersion have resolutions that do not represent a genuine fix. filter_unresolved() treats any resolution in {None, 'Unresolved', 'Duplicate', 'Invalid', 'Not A Problem', 'Not A Bug', \"Won't Fix\", 'Incomplete', 'Cannot Reproduce', 'Later', 'Works for Me', 'Workaround', 'Information Provided'} as not-really-fixed. The check exists to guarantee release notes only list work actually shipped, blocking the release until every tagged issue is either truly Fixed or untagged.","triggerScenarios":"Calling generate(version) (or running `python notes.py <version>`) such that the JQL query `project=KAFKA and fixVersion=<version>` returns at least one issue, and at least one returned issue has issue.fields.resolution equal to None or whose .name is one of the UNRESOLVED_RESOLUTIONS listed in filter_unresolved(). The exception is raised at notes.py:152 after building issue_list from those issues.","commonSituations":"Release manager generates notes before all issues are properly resolved; an issue was closed as Duplicate/Won't Fix/Invalid but its fixVersion was never cleared; bulk JIRA edits or version renames left stale fixVersion tags; an issue is still genuinely open (resolution=None) yet already carries the upcoming version; a sub-task was moved out but the parent kept the fixVersion.","solutions":["Read the issue_list in the error message, then in JIRA remove the fixVersion=<version> from every issue that was NOT actually fixed in this release (duplicates, won't-fix, invalid, cannot-reproduce).","For issues that ARE fixed but show resolution=None, set their JIRA resolution to 'Fixed' (or another acceptable resolution) and reopen the script.","For issues still in progress, move their fixVersion to a future release so they drop out of this query.","Re-run `python notes.py <version>`; it only succeeds once filter_unresolved() returns an empty list.","If the release is genuinely incomplete, do not suppress this error - finish the work in JIRA first."],"exampleFix":"// This is a JIRA data error, not a code change. No edit to notes.py is correct.\n\n// before (JIRA state causing the error):\n//   KAFKA-12345  fixVersion=3.8.0  resolution=Duplicate\n//   KAFKA-12346  fixVersion=3.8.0  resolution=None\n//   KAFKA-12347  fixVersion=3.8.0  resolution=Won't Fix\n// -> `python notes.py 3.8.0` raises the error listing all three.\n\n// after (fix in JIRA, then re-run):\n//   KAFKA-12345  (remove fixVersion 3.8.0)         // was a duplicate\n//   KAFKA-12346  fixVersion=3.8.0  resolution=Fixed  // now genuinely fixed\n//   KAFKA-12347  fixVersion=3.9.0  resolution=None    // moved to next release\n// -> `python notes.py 3.8.0` now emits RELEASE_NOTES.html successfully.","handlingStrategy":"validation","validationCode":"# Run BEFORE calling generate(version) to fail fast with a clear message.\n# Reuses the same query + filter so it matches notes.py exactly.\nfrom release import notes\n\ndef assert_release_ready(version):\n    issues = notes.query(f\"project=KAFKA and fixVersion={version}\")\n    if not issues:\n        raise ValueError(f\"No issues found for {version} - wrong version string?\")\n    unresolved = notes.filter_unresolved(issues)\n    if unresolved:\n        keys = \", \".join(i.key for i in unresolved)\n        raise ValueError(\n            f\"Release {version} not ready. Untag/move/fix these in JIRA first: {keys}\"\n        )\n    return issues  # safe to call notes.generate(version) now\n\nissues = assert_release_ready(\"3.8.0\")\nhtml = notes.generate(\"3.8.0\")","typeGuard":null,"tryCatchPattern":"# The script itself (notes.py:164-174) already wraps generate() - mirror it.\nimport sys\nfrom release import notes\n\ntry:\n    print(notes.generate(version))\nexcept Exception as e:\n    # Surface the embedded issue_list so the release manager can act on JIRA.\n    print(e, file=sys.stderr)\n    sys.exit(1)","preventionTips":["Keep JIRA hygiene: when closing an issue as Duplicate/Won't Fix/Invalid, remove the fixVersion in the same edit.","Run the assert_release_ready pre-check above as a CI/release gate before generating notes.","When renaming/moving a version in JIRA bulk operations, audit fixVersion fields on all affected issues afterward.","Treat this error as authoritative - do not patch notes.py to skip filter_unresolved(); fix the JIRA data instead."],"tags":["release","jira","release-notes","apache-kafka","release-management","workflow","validation"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}