Skip to content

fix: use REST API for team resolution (team_by_slug missing in github3.py v4.0.1)#25

Merged
zkoppert merged 2 commits intomainfrom
fix/team-by-slug-rest-api
Mar 14, 2026
Merged

fix: use REST API for team resolution (team_by_slug missing in github3.py v4.0.1)#25
zkoppert merged 2 commits intomainfrom
fix/team-by-slug-rest-api

Conversation

@zkoppert
Copy link
Contributor

@zkoppert zkoppert commented Mar 14, 2026

Problem

get_team_members() in auth.py calls organization.team_by_slug(slug), but this method does not exist in github3.py v4.0.1. The call raises an AttributeError that gets caught by the broad except block, displaying just "team_by_slug" as the error - which is misleading since it suggests a permissions issue.

Root cause

github3.py v4.0.1 has these team methods on Organization:

  • team(id) - lookup by numeric ID
  • team_by_name(slug) - lookup by slug (misleading name, actually hits GET /orgs/{org}/teams/{slug})
  • teams() - list all teams

There is no team_by_slug. It was requested in github3.py#948 but the maintainer shipped it as team_by_name instead. The method never existed in any released version.

How we found this

Debugged in github/new-user-experience where FILTER_TEAMS was configured:

  1. Added a curl debug step before the Docker action to test the token against the Teams API
  2. curl returned HTTP 200 - the token and endpoint work fine
  3. Inside the container, github3.py raised AttributeError("team_by_slug")
  4. Confirmed locally: "team_by_slug" in dir(github3.orgs.Organization)False
  5. Found the fix: "team_by_name" in dir(github3.orgs.Organization)True, and inspecting the source shows it takes a slug and hits the same endpoint

Debug run: https://github.com/github/new-user-experience/actions/runs/23080465650/job/67048787353

Why tests did not catch this

The existing tests use MagicMock() which auto-creates any attribute accessed on it. So mock_org.team_by_slug.return_value = mock_team worked perfectly in tests - MagicMock happily faked a method that does not exist on the real class.

Added a guard test that checks the real github3.orgs.Organization class directly to prevent this class of bug in the future.

Fix

  • auth.py: Replace organization.team_by_slug(team_slug) with organization.team_by_name(team_slug)
  • test_auth.py: Update mocks to use team_by_name + add a guard test verifying the method exists on the real class

Local testing

Ran the action locally with DRY_RUN=true against github/new-user-experience:

Single team:

Resolving FILTER_TEAMS...
  Resolved team github/nux-reviewers: 6 member(s)
Combined 18 FILTER_AUTHORS + team members = 20 unique author(s)

Scanning github/new-user-experience...
  Found 3 open PRs, analyzing for conflicts...
  ✅ No conflicts detected

Multiple teams:

Resolving FILTER_TEAMS...
  Resolved team github/nux-reviewers: 6 member(s)
  Resolved team github/pull-requests-reviewers: 22 member(s)
Combined 18 FILTER_AUTHORS + team members = 35 unique author(s)

Scanning github/new-user-experience...
  Found 3 open PRs, analyzing for conflicts...
  ✅ No conflicts detected

Both teams that previously failed with team_by_slug now resolve correctly.

CI

  • All 204 tests pass (99% coverage)
  • make lint clean (pylint 10.00/10, mypy clean, black formatted)

@github-actions github-actions bot added the fix Bug fix label Mar 14, 2026
get_team_members() called organization.team_by_slug() which does not
exist in github3.py v4.0.1, causing an AttributeError displayed as
just 'team_by_slug' whenever FILTER_TEAMS was used.

The existing team_by_name() method does the same thing (accepts a slug,
hits GET /orgs/{org}/teams/{slug}) despite its misleading name.

Discovered by adding a curl debug step to the workflow in
github/new-user-experience which confirmed the token returns HTTP 200
for the teams endpoint outside the Docker container, proving the issue
is inside github3.py, not a permissions problem.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@zkoppert zkoppert force-pushed the fix/team-by-slug-rest-api branch from 8fdea3b to 42fc7d6 Compare March 14, 2026 04:46
MagicMock auto-creates any attribute accessed on it, so the original
tests couldn't catch that team_by_slug didn't exist on the real
github3.orgs.Organization class. This test checks the real class
directly to prevent similar issues if the library changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@zkoppert zkoppert self-assigned this Mar 14, 2026
@zkoppert zkoppert marked this pull request as ready for review March 14, 2026 05:10
@zkoppert zkoppert requested a review from jmeridth as a code owner March 14, 2026 05:10
@zkoppert zkoppert merged commit 179b1e8 into main Mar 14, 2026
39 checks passed
@zkoppert zkoppert deleted the fix/team-by-slug-rest-api branch March 14, 2026 05:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants