Skip to content

Webhook discussion reply answers fail to get parsed #239

@trag1c

Description

@trag1c

GitHub's at fault here :( To reproduce, try githubkit.webhooks.parse_obj on the attached event payload.

Event payload (Python dict)
{
    "action": "answered",
    "discussion": {
        "repository_url": "https://api.github.com/repos/ghrebote/test",
        "category": {
            "id": 45773373,
            "node_id": "DIC_kwDOOQ21Wc4CunI9",
            "repository_id": 957199705,
            "emoji": ":pray:",
            "name": "Q&A",
            "description": "Ask the community for help",
            "created_at": "2025-08-26T18:59:39.000+02:00",
            "updated_at": "2025-08-26T18:59:39.000+02:00",
            "slug": "q-a",
            "is_answerable": True,
        },
        "answer_html_url": "https://github.com/ghrebote/test/discussions/23#discussioncomment-14608910",
        "answer_chosen_at": "2025-10-06T22:49:55.000+02:00",
        "answer_chosen_by": {
            "login": "trag1c",
            "id": 77130613,
            "node_id": "MDQ6VXNlcjc3MTMwNjEz",
            "avatar_url": "https://avatars.githubusercontent.com/u/77130613?v=4",
            "gravatar_id": "",
            "url": "https://api.github.com/users/trag1c",
            "html_url": "https://github.com/trag1c",
            "followers_url": "https://api.github.com/users/trag1c/followers",
            "following_url": "https://api.github.com/users/trag1c/following{/other_user}",
            "gists_url": "https://api.github.com/users/trag1c/gists{/gist_id}",
            "starred_url": "https://api.github.com/users/trag1c/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/trag1c/subscriptions",
            "organizations_url": "https://api.github.com/users/trag1c/orgs",
            "repos_url": "https://api.github.com/users/trag1c/repos",
            "events_url": "https://api.github.com/users/trag1c/events{/privacy}",
            "received_events_url": "https://api.github.com/users/trag1c/received_events",
            "type": "User",
            "user_view_type": "public",
            "site_admin": False,
        },
        "html_url": "https://github.com/ghrebote/test/discussions/23",
        "id": 8923208,
        "node_id": "D_kwDOOQ21Wc4AiChI",
        "number": 23,
        "title": "Have you ever seen a bobr in real life?",
        "user": {
            "login": "CoderJoshDK",
            "id": 74162303,
            "node_id": "MDQ6VXNlcjc0MTYyMzAz",
            "avatar_url": "https://avatars.githubusercontent.com/u/74162303?v=4",
            "gravatar_id": "",
            "url": "https://api.github.com/users/CoderJoshDK",
            "html_url": "https://github.com/CoderJoshDK",
            "followers_url": "https://api.github.com/users/CoderJoshDK/followers",
            "following_url": "https://api.github.com/users/CoderJoshDK/following{/other_user}",
            "gists_url": "https://api.github.com/users/CoderJoshDK/gists{/gist_id}",
            "starred_url": "https://api.github.com/users/CoderJoshDK/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/CoderJoshDK/subscriptions",
            "organizations_url": "https://api.github.com/users/CoderJoshDK/orgs",
            "repos_url": "https://api.github.com/users/CoderJoshDK/repos",
            "events_url": "https://api.github.com/users/CoderJoshDK/events{/privacy}",
            "received_events_url": "https://api.github.com/users/CoderJoshDK/received_events",
            "type": "User",
            "user_view_type": "public",
            "site_admin": False,
        },
        "labels": [],
        "state": "open",
        "state_reason": None,
        "locked": False,
        "comments": 2,
        "created_at": "2025-09-20T16:10:21Z",
        "updated_at": "2025-10-06T20:49:55Z",
        "author_association": "NONE",
        "active_lock_reason": None,
        "body": "I for one have not. Very sad.",
        "reactions": {
            "url": "https://api.github.com/repos/ghrebote/test/discussions/23/reactions",
            "total_count": 0,
            "+1": 0,
            "-1": 0,
            "laugh": 0,
            "hooray": 0,
            "confused": 0,
            "heart": 0,
            "rocket": 0,
            "eyes": 0,
        },
        "timeline_url": "https://api.github.com/repos/ghrebote/test/discussions/23/timeline",
    },
    "answer": {
        "id": 14608910,
        "node_id": "DC_kwDOOQ21Wc4A3uoO",
        "html_url": "https://github.com/ghrebote/test/discussions/23#discussioncomment-14608910",
        "parent_id": 14608909,
        "child_comment_count": 0,
        "repository_url": "ghrebote/test",
        "discussion_id": 8923208,
        "author_association": "CONTRIBUTOR",
        "user": {
            "login": "trag1c",
            "id": 77130613,
            "node_id": "MDQ6VXNlcjc3MTMwNjEz",
            "avatar_url": "https://avatars.githubusercontent.com/u/77130613?v=4",
            "gravatar_id": "",
            "url": "https://api.github.com/users/trag1c",
            "html_url": "https://github.com/trag1c",
            "followers_url": "https://api.github.com/users/trag1c/followers",
            "following_url": "https://api.github.com/users/trag1c/following{/other_user}",
            "gists_url": "https://api.github.com/users/trag1c/gists{/gist_id}",
            "starred_url": "https://api.github.com/users/trag1c/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/trag1c/subscriptions",
            "organizations_url": "https://api.github.com/users/trag1c/orgs",
            "repos_url": "https://api.github.com/users/trag1c/repos",
            "events_url": "https://api.github.com/users/trag1c/events{/privacy}",
            "received_events_url": "https://api.github.com/users/trag1c/received_events",
            "type": "User",
            "user_view_type": "public",
            "site_admin": False,
        },
        "created_at": "2025-10-06T20:49:33Z",
        "updated_at": "2025-10-06T20:49:33Z",
        "body": "bar",
        "reactions": {
            "url": "https://api.github.com/repos/ghrebote/test/discussions/comments/14608910/reactions",
            "total_count": 0,
            "+1": 0,
            "-1": 0,
            "laugh": 0,
            "hooray": 0,
            "confused": 0,
            "heart": 0,
            "rocket": 0,
            "eyes": 0,
        },
    },
    "repository": {
        "id": 957199705,
        "node_id": "R_kgDOOQ21WQ",
        "name": "test",
        "full_name": "ghrebote/test",
        "private": False,
        "owner": {
            "login": "ghrebote",
            "id": 205458711,
            "node_id": "O_kgDODD8NFw",
            "avatar_url": "https://avatars.githubusercontent.com/u/205458711?v=4",
            "gravatar_id": "",
            "url": "https://api.github.com/users/ghrebote",
            "html_url": "https://github.com/ghrebote",
            "followers_url": "https://api.github.com/users/ghrebote/followers",
            "following_url": "https://api.github.com/users/ghrebote/following{/other_user}",
            "gists_url": "https://api.github.com/users/ghrebote/gists{/gist_id}",
            "starred_url": "https://api.github.com/users/ghrebote/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/ghrebote/subscriptions",
            "organizations_url": "https://api.github.com/users/ghrebote/orgs",
            "repos_url": "https://api.github.com/users/ghrebote/repos",
            "events_url": "https://api.github.com/users/ghrebote/events{/privacy}",
            "received_events_url": "https://api.github.com/users/ghrebote/received_events",
            "type": "Organization",
            "user_view_type": "public",
            "site_admin": False,
        },
        "html_url": "https://github.com/ghrebote/test",
        "description": None,
        "fork": False,
        "url": "https://api.github.com/repos/ghrebote/test",
        "forks_url": "https://api.github.com/repos/ghrebote/test/forks",
        "keys_url": "https://api.github.com/repos/ghrebote/test/keys{/key_id}",
        "collaborators_url": "https://api.github.com/repos/ghrebote/test/collaborators{/collaborator}",
        "teams_url": "https://api.github.com/repos/ghrebote/test/teams",
        "hooks_url": "https://api.github.com/repos/ghrebote/test/hooks",
        "issue_events_url": "https://api.github.com/repos/ghrebote/test/issues/events{/number}",
        "events_url": "https://api.github.com/repos/ghrebote/test/events",
        "assignees_url": "https://api.github.com/repos/ghrebote/test/assignees{/user}",
        "branches_url": "https://api.github.com/repos/ghrebote/test/branches{/branch}",
        "tags_url": "https://api.github.com/repos/ghrebote/test/tags",
        "blobs_url": "https://api.github.com/repos/ghrebote/test/git/blobs{/sha}",
        "git_tags_url": "https://api.github.com/repos/ghrebote/test/git/tags{/sha}",
        "git_refs_url": "https://api.github.com/repos/ghrebote/test/git/refs{/sha}",
        "trees_url": "https://api.github.com/repos/ghrebote/test/git/trees{/sha}",
        "statuses_url": "https://api.github.com/repos/ghrebote/test/statuses/{sha}",
        "languages_url": "https://api.github.com/repos/ghrebote/test/languages",
        "stargazers_url": "https://api.github.com/repos/ghrebote/test/stargazers",
        "contributors_url": "https://api.github.com/repos/ghrebote/test/contributors",
        "subscribers_url": "https://api.github.com/repos/ghrebote/test/subscribers",
        "subscription_url": "https://api.github.com/repos/ghrebote/test/subscription",
        "commits_url": "https://api.github.com/repos/ghrebote/test/commits{/sha}",
        "git_commits_url": "https://api.github.com/repos/ghrebote/test/git/commits{/sha}",
        "comments_url": "https://api.github.com/repos/ghrebote/test/comments{/number}",
        "issue_comment_url": "https://api.github.com/repos/ghrebote/test/issues/comments{/number}",
        "contents_url": "https://api.github.com/repos/ghrebote/test/contents/{+path}",
        "compare_url": "https://api.github.com/repos/ghrebote/test/compare/{base}...{head}",
        "merges_url": "https://api.github.com/repos/ghrebote/test/merges",
        "archive_url": "https://api.github.com/repos/ghrebote/test/{archive_format}{/ref}",
        "downloads_url": "https://api.github.com/repos/ghrebote/test/downloads",
        "issues_url": "https://api.github.com/repos/ghrebote/test/issues{/number}",
        "pulls_url": "https://api.github.com/repos/ghrebote/test/pulls{/number}",
        "milestones_url": "https://api.github.com/repos/ghrebote/test/milestones{/number}",
        "notifications_url": "https://api.github.com/repos/ghrebote/test/notifications{?since,all,participating}",
        "labels_url": "https://api.github.com/repos/ghrebote/test/labels{/name}",
        "releases_url": "https://api.github.com/repos/ghrebote/test/releases{/id}",
        "deployments_url": "https://api.github.com/repos/ghrebote/test/deployments",
        "created_at": "2025-03-29T19:38:45Z",
        "updated_at": "2025-09-06T21:48:45Z",
        "pushed_at": "2025-09-06T21:48:42Z",
        "git_url": "git://github.com/ghrebote/test.git",
        "ssh_url": "git@github.com:ghrebote/test.git",
        "clone_url": "https://github.com/ghrebote/test.git",
        "svn_url": "https://github.com/ghrebote/test",
        "homepage": None,
        "size": 35,
        "stargazers_count": 0,
        "watchers_count": 0,
        "language": "Python",
        "has_issues": True,
        "has_projects": True,
        "has_downloads": True,
        "has_wiki": False,
        "has_pages": False,
        "has_discussions": True,
        "forks_count": 0,
        "mirror_url": None,
        "archived": False,
        "disabled": False,
        "open_issues_count": 3,
        "license": None,
        "allow_forking": True,
        "is_template": False,
        "web_commit_signoff_required": False,
        "topics": [],
        "visibility": "public",
        "forks": 0,
        "open_issues": 3,
        "watchers": 0,
        "default_branch": "main",
        "custom_properties": {},
    },
    "organization": {
        "login": "ghrebote",
        "id": 205458711,
        "node_id": "O_kgDODD8NFw",
        "url": "https://api.github.com/orgs/ghrebote",
        "repos_url": "https://api.github.com/orgs/ghrebote/repos",
        "events_url": "https://api.github.com/orgs/ghrebote/events",
        "hooks_url": "https://api.github.com/orgs/ghrebote/hooks",
        "issues_url": "https://api.github.com/orgs/ghrebote/issues",
        "members_url": "https://api.github.com/orgs/ghrebote/members{/member}",
        "public_members_url": "https://api.github.com/orgs/ghrebote/public_members{/member}",
        "avatar_url": "https://avatars.githubusercontent.com/u/205458711?v=4",
        "description": None,
    },
    "sender": {
        "login": "trag1c",
        "id": 77130613,
        "node_id": "MDQ6VXNlcjc3MTMwNjEz",
        "avatar_url": "https://avatars.githubusercontent.com/u/77130613?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/trag1c",
        "html_url": "https://github.com/trag1c",
        "followers_url": "https://api.github.com/users/trag1c/followers",
        "following_url": "https://api.github.com/users/trag1c/following{/other_user}",
        "gists_url": "https://api.github.com/users/trag1c/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/trag1c/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/trag1c/subscriptions",
        "organizations_url": "https://api.github.com/users/trag1c/orgs",
        "repos_url": "https://api.github.com/users/trag1c/repos",
        "events_url": "https://api.github.com/users/trag1c/events{/privacy}",
        "received_events_url": "https://api.github.com/users/trag1c/received_events",
        "type": "User",
        "user_view_type": "public",
        "site_admin": False,
    },
}

In Webhook events and payloads, GitHub says that discussion.answered must have parent_id set to null, although when a discussion answer is a reply to another comment (so, it has a parent) they send an int, making the model fail to validate the payload. It would be great if a workaround can be added for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    WebHookbugSomething isn't workingschemaschema related

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions