)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"ec49a9806a9b8540c382925c0dce35e55c51356c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"f29a90ff_59d764db","updated":"2026-10-07 12:24:44.000000000","message":"have you adressed the client issue?","commit_id":"d55414606769daa22e1e346a1d513e55999f3970"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"328c68c165b780776934fe51e5f0332cbfe40a89","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"ac039016_2b820989","in_reply_to":"f29a90ff_59d764db","updated":"2026-10-07 12:49:15.000000000","message":"yes, I pushed https://review.opendev.org/c/openstack/python-watcherclient/+/1008319 and added a depends-on for that patch here. The idea is to temporarily handle both cases in the client until this merges and then only read the expected format (that is done in https://review.opendev.org/c/openstack/python-watcherclient/+/1008429/1)","commit_id":"d55414606769daa22e1e346a1d513e55999f3970"}],"releasenotes/notes/fix-double-encoding-error-responses-b9b57e1bd0a74b40.yaml":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"393076749bcd2685f4d04622ceaec2503473c292","unresolved":false,"context_lines":[{"line_number":10,"context_line":"    ``error_message`` value should access it directly as a dict"},{"line_number":11,"context_line":"    (e.g. ``response[\u0027error_message\u0027][\u0027faultstring\u0027]``). For more"},{"line_number":12,"context_line":"    details, please see"},{"line_number":13,"context_line":"    `Bug #2169114 \u003chttps://bugs.launchpad.net/watcher/+bug/2169114\u003e_`."}],"source_content_type":"text/x-yaml","patch_set":4,"id":"6df4f658_fa58c885","line":13,"updated":"2026-10-07 13:13:17.000000000","message":"The new release note terminates the embedded-URI link with the underscore inside the closing backticks (...+bug/2169114\u003e_), which reStructuredText does not recognize as a hyperlink reference. docutils parses the phrase as a title_reference, so the published release notes display the raw URL with a stray trailing underscore as literal text instead of a clickable Bug #2169114 link.\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: Operators and clients reading the rendered upgrade notes cannot follow the bug reference for the error_message format change; the raw URL and an underscore appear as literal text, lowering the quality of the permanent release documentation shipped with this API change.\n\n**Suggestion**:\nMove the underscore outside the closing backticks so the link is recognized: `Bug #2169114 \u003chttps://bugs.launchpad.net/watcher/+bug/2169114\u003e`_ (keep the trailing period outside the link text).","commit_id":"4f06a831f95eb4d8bd22bfb998c15ee08631079f"}],"watcher/api/middleware/parsable_error.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"ec49a9806a9b8540c382925c0dce35e55c51356c","unresolved":true,"context_lines":[{"line_number":19,"context_line":"Based on pecan.middleware.errordocument"},{"line_number":20,"context_line":"\"\"\""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from contextlib import suppress"},{"line_number":23,"context_line":"from xml import etree as et"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"import webob"}],"source_content_type":"text/x-python","patch_set":3,"id":"9d37d3b8_6e1ada19","line":22,"range":{"start_line":22,"start_character":23,"end_line":22,"end_character":31},"updated":"2026-10-07 12:24:44.000000000","message":"you are not ment to import functions, context manager, decorators or any other symbol that is not a module\n```suggestion\nimport contextlib\n\n```","commit_id":"d55414606769daa22e1e346a1d513e55999f3970"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"328c68c165b780776934fe51e5f0332cbfe40a89","unresolved":false,"context_lines":[{"line_number":19,"context_line":"Based on pecan.middleware.errordocument"},{"line_number":20,"context_line":"\"\"\""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from contextlib import suppress"},{"line_number":23,"context_line":"from xml import etree as et"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"import webob"}],"source_content_type":"text/x-python","patch_set":3,"id":"b8aea6e1_76479dce","line":22,"range":{"start_line":22,"start_character":23,"end_line":22,"end_character":31},"in_reply_to":"9d37d3b8_6e1ada19","updated":"2026-10-07 12:49:15.000000000","message":"Done","commit_id":"d55414606769daa22e1e346a1d513e55999f3970"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"ec49a9806a9b8540c382925c0dce35e55c51356c","unresolved":true,"context_lines":[{"line_number":71,"context_line":"        app_iter \u003d self.app(environ, replacement_start_response)"},{"line_number":72,"context_line":"        if (state[\u0027status_code\u0027] // 100) not in (2, 3):"},{"line_number":73,"context_line":"            req \u003d webob.Request(environ)"},{"line_number":74,"context_line":"            if ("},{"line_number":75,"context_line":"                req.accept.best_match([\u0027application/json\u0027, \u0027application/xml\u0027])"},{"line_number":76,"context_line":"                \u003d\u003d \u0027application/xml\u0027"},{"line_number":77,"context_line":"            ):"},{"line_number":78,"context_line":"                try:"},{"line_number":79,"context_line":"                    # simple check xml is valid"},{"line_number":80,"context_line":"                    body \u003d ["},{"line_number":81,"context_line":"                        et.ElementTree.tostring("},{"line_number":82,"context_line":"                            et.ElementTree.Element("},{"line_number":83,"context_line":"                                \u0027error_message\u0027, text\u003d\u0027\\n\u0027.join(app_iter)"},{"line_number":84,"context_line":"                            )"},{"line_number":85,"context_line":"                        )"},{"line_number":86,"context_line":"                    ]"},{"line_number":87,"context_line":"                except et.ElementTree.ParseError as err:"},{"line_number":88,"context_line":"                    LOG.error(\u0027Error parsing HTTP response: %s\u0027, err)"},{"line_number":89,"context_line":"                    body \u003d ["},{"line_number":90,"context_line":"                        \u0027\u003cerror_message\u003e{}\u003c/error_message\u003e\u0027.format("},{"line_number":91,"context_line":"                            state[\u0027status_code\u0027]"},{"line_number":92,"context_line":"                        )"},{"line_number":93,"context_line":"                    ]"},{"line_number":94,"context_line":"                state[\u0027headers\u0027].append((\u0027Content-Type\u0027, \u0027application/xml\u0027))"},{"line_number":95,"context_line":"            else:"},{"line_number":96,"context_line":"                err_message \u003d b\u0027\u0027.join(app_iter).decode(\u0027utf-8\u0027)"},{"line_number":97,"context_line":"                with suppress(ValueError):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a88dd55_38c92fc2","line":94,"range":{"start_line":74,"start_character":5,"end_line":94,"end_character":76},"updated":"2026-10-07 12:24:44.000000000","message":"we need to revisit this later as a seperat bug\n\nthere is not case weher we shoudl ever return an xml body.\n\nxml error and rest apis in general were removed form all service over a decade ago as part of a cross project goal/tc effort.\n\nthe current api guidline specificly are writen in terms of json based api partly for that reason.\n\nhttps://specs.openstack.org/openstack/api-wg/","commit_id":"d55414606769daa22e1e346a1d513e55999f3970"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"0dc3933da7cbbac6125da08a85b740ab781548ae","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        app_iter \u003d self.app(environ, replacement_start_response)"},{"line_number":72,"context_line":"        if (state[\u0027status_code\u0027] // 100) not in (2, 3):"},{"line_number":73,"context_line":"            req \u003d webob.Request(environ)"},{"line_number":74,"context_line":"            if ("},{"line_number":75,"context_line":"                req.accept.best_match([\u0027application/json\u0027, \u0027application/xml\u0027])"},{"line_number":76,"context_line":"                \u003d\u003d \u0027application/xml\u0027"},{"line_number":77,"context_line":"            ):"},{"line_number":78,"context_line":"                try:"},{"line_number":79,"context_line":"                    # simple check xml is valid"},{"line_number":80,"context_line":"                    body \u003d ["},{"line_number":81,"context_line":"                        et.ElementTree.tostring("},{"line_number":82,"context_line":"                            et.ElementTree.Element("},{"line_number":83,"context_line":"                                \u0027error_message\u0027, text\u003d\u0027\\n\u0027.join(app_iter)"},{"line_number":84,"context_line":"                            )"},{"line_number":85,"context_line":"                        )"},{"line_number":86,"context_line":"                    ]"},{"line_number":87,"context_line":"                except et.ElementTree.ParseError as err:"},{"line_number":88,"context_line":"                    LOG.error(\u0027Error parsing HTTP response: %s\u0027, err)"},{"line_number":89,"context_line":"                    body \u003d ["},{"line_number":90,"context_line":"                        \u0027\u003cerror_message\u003e{}\u003c/error_message\u003e\u0027.format("},{"line_number":91,"context_line":"                            state[\u0027status_code\u0027]"},{"line_number":92,"context_line":"                        )"},{"line_number":93,"context_line":"                    ]"},{"line_number":94,"context_line":"                state[\u0027headers\u0027].append((\u0027Content-Type\u0027, \u0027application/xml\u0027))"},{"line_number":95,"context_line":"            else:"},{"line_number":96,"context_line":"                err_message \u003d b\u0027\u0027.join(app_iter).decode(\u0027utf-8\u0027)"},{"line_number":97,"context_line":"                with suppress(ValueError):"}],"source_content_type":"text/x-python","patch_set":3,"id":"fac5542a_d0091434","line":94,"range":{"start_line":74,"start_character":5,"end_line":94,"end_character":76},"in_reply_to":"1c10360b_3cb6d0da","updated":"2026-10-07 13:10:25.000000000","message":"Acknowledged","commit_id":"d55414606769daa22e1e346a1d513e55999f3970"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"328c68c165b780776934fe51e5f0332cbfe40a89","unresolved":true,"context_lines":[{"line_number":71,"context_line":"        app_iter \u003d self.app(environ, replacement_start_response)"},{"line_number":72,"context_line":"        if (state[\u0027status_code\u0027] // 100) not in (2, 3):"},{"line_number":73,"context_line":"            req \u003d webob.Request(environ)"},{"line_number":74,"context_line":"            if ("},{"line_number":75,"context_line":"                req.accept.best_match([\u0027application/json\u0027, \u0027application/xml\u0027])"},{"line_number":76,"context_line":"                \u003d\u003d \u0027application/xml\u0027"},{"line_number":77,"context_line":"            ):"},{"line_number":78,"context_line":"                try:"},{"line_number":79,"context_line":"                    # simple check xml is valid"},{"line_number":80,"context_line":"                    body \u003d ["},{"line_number":81,"context_line":"                        et.ElementTree.tostring("},{"line_number":82,"context_line":"                            et.ElementTree.Element("},{"line_number":83,"context_line":"                                \u0027error_message\u0027, text\u003d\u0027\\n\u0027.join(app_iter)"},{"line_number":84,"context_line":"                            )"},{"line_number":85,"context_line":"                        )"},{"line_number":86,"context_line":"                    ]"},{"line_number":87,"context_line":"                except et.ElementTree.ParseError as err:"},{"line_number":88,"context_line":"                    LOG.error(\u0027Error parsing HTTP response: %s\u0027, err)"},{"line_number":89,"context_line":"                    body \u003d ["},{"line_number":90,"context_line":"                        \u0027\u003cerror_message\u003e{}\u003c/error_message\u003e\u0027.format("},{"line_number":91,"context_line":"                            state[\u0027status_code\u0027]"},{"line_number":92,"context_line":"                        )"},{"line_number":93,"context_line":"                    ]"},{"line_number":94,"context_line":"                state[\u0027headers\u0027].append((\u0027Content-Type\u0027, \u0027application/xml\u0027))"},{"line_number":95,"context_line":"            else:"},{"line_number":96,"context_line":"                err_message \u003d b\u0027\u0027.join(app_iter).decode(\u0027utf-8\u0027)"},{"line_number":97,"context_line":"                with suppress(ValueError):"}],"source_content_type":"text/x-python","patch_set":3,"id":"1c10360b_3cb6d0da","line":94,"range":{"start_line":74,"start_character":5,"end_line":94,"end_character":76},"in_reply_to":"9a88dd55_38c92fc2","updated":"2026-10-07 12:49:15.000000000","message":"good point, I\u0027ve opened https://bugs.launchpad.net/watcher/+bug/2169843 to track the removal, thanks for the link!","commit_id":"d55414606769daa22e1e346a1d513e55999f3970"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"ec49a9806a9b8540c382925c0dce35e55c51356c","unresolved":true,"context_lines":[{"line_number":94,"context_line":"                state[\u0027headers\u0027].append((\u0027Content-Type\u0027, \u0027application/xml\u0027))"},{"line_number":95,"context_line":"            else:"},{"line_number":96,"context_line":"                err_message \u003d b\u0027\u0027.join(app_iter).decode(\u0027utf-8\u0027)"},{"line_number":97,"context_line":"                with suppress(ValueError):"},{"line_number":98,"context_line":"                    # WSME encodes error bodies as JSON before they reach here;"},{"line_number":99,"context_line":"                    # decode first to avoid double-encoding in dumps()."},{"line_number":100,"context_line":"                    err_message \u003d jsonutils.loads(err_message)"}],"source_content_type":"text/x-python","patch_set":3,"id":"2c93da75_4ab5b54c","line":97,"range":{"start_line":97,"start_character":21,"end_line":97,"end_character":29},"updated":"2026-10-07 12:24:44.000000000","message":"```suggestion\n                with contextlib.suppress(ValueError):\n```","commit_id":"d55414606769daa22e1e346a1d513e55999f3970"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"328c68c165b780776934fe51e5f0332cbfe40a89","unresolved":false,"context_lines":[{"line_number":94,"context_line":"                state[\u0027headers\u0027].append((\u0027Content-Type\u0027, \u0027application/xml\u0027))"},{"line_number":95,"context_line":"            else:"},{"line_number":96,"context_line":"                err_message \u003d b\u0027\u0027.join(app_iter).decode(\u0027utf-8\u0027)"},{"line_number":97,"context_line":"                with suppress(ValueError):"},{"line_number":98,"context_line":"                    # WSME encodes error bodies as JSON before they reach here;"},{"line_number":99,"context_line":"                    # decode first to avoid double-encoding in dumps()."},{"line_number":100,"context_line":"                    err_message \u003d jsonutils.loads(err_message)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3ca97331_37500c03","line":97,"range":{"start_line":97,"start_character":21,"end_line":97,"end_character":29},"in_reply_to":"2c93da75_4ab5b54c","updated":"2026-10-07 12:49:15.000000000","message":"Done","commit_id":"d55414606769daa22e1e346a1d513e55999f3970"}]}
