Conversation
…itHub org lookup fails POST /api/team/approve 500'd on fall-2026 (test): the event's github_org was stored as "https://github.com/Opportunity-Hack-2026" and approve_team passed it verbatim to PyGithub's get_organization -> UnknownObjectException 404, which create_github_repo did not catch (only create_repo was wrapped) and approve_team only catches ValueError. - validators.normalize_github_org(): strip https://github.com/, www., @, trailing path and whitespace (mirrors the frontend's githubOrgSlug). validate_hackathon_data_partial now stores the normalized slug, which covers both create and update since save_hackathon uses its output. - approve_team: normalize the stored value too (events saved before this fix) and return an actionable message when it is empty. - common/utils/github.py: get_github_organization() wraps the lookup and raises ValueError distinguishing 404 (bad slug / no such org) from 401/403 (token). create_github_repo resolves the org once and passes it into does_repo_exist instead of looking it up twice. - Tests for the normalizer and the partial validator. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
"Approve Team" on the test event
fall-2026returned a 500. Fly logs:The event's
github_orgis stored ashttps://github.com/Opportunity-Hack-2026(a pasted URL). It was handed verbatim to PyGithub, which requested/orgs/https://github.com/Opportunity-Hack-2026→ 404. The org itself exists (/orgs/Opportunity-Hack-2026→ 200), andGITHUB_TOKENis fine (a bad token gives 401). The exception escaped becausecreate_github_repoonly wrappedcreate_repo, andapprove_teamonly catchesValueError.What
common/utils/validators.py: newnormalize_github_org(raw)— stripshttps://github.com/,www., a leading@, any trailing path, and whitespace (mirrors the frontend'sgithubOrgSlug).validate_hackathon_data_partialnow stores the normalized slug;save_hackathonuses its output for both create and update, so every save path is covered.api/teams/teams_service.py::approve_team: normalizes the stored value too (events saved before this fix) and returns an actionable message when it's empty.common/utils/github.py:get_github_organization(g, org_name)wraps the lookup and raisesValueErrorwhose message distinguishes 404 (bad slug / no such org) from 401/403 (token).create_github_reporesolves the org once and passes it intodoes_repo_exist(was a secondget_organizationcall).approve_team's existingexcept ValueErrorturns this into200 {success: false, message}.test/common/utils/test_validators.py(normalizer table + partial-validator behaviour).Not changed (follow-up if wanted):
api/leaderboard/leaderboard_service.pyuses the rawhackathon["github_org"]as a Firestore document id, so a legacy URL value there would still break until that event is re-saved.Frontend companion PR (normalizes on blur + shows the
success:falsemessage, which the admin UI currently swallows): opportunity-hack/frontend-ohack.dev#369.Test plan
PYTHONPATH=. python -m pytest test/common/utils/test_validators.py→ 49 passed.PATCH /api/messages/hackathonforfall-2026withgithub_org: "https://github.com/Opportunity-Hack-2026/"→GET /api/messages/hackathon/fall-2026returns"github_org": "Opportunity-Hack-2026"./admin/hackathons/fall-2026?section=teams→ open theadadadteam → Nonprofit Assignment → pick nonprofit → Approve Team → succeeds; repoadadad-NMTSAEducationPlatfoappears ingithub.com/Opportunity-Hack-2026; no traceback in Fly logs.github_orgtono-such-org-xyz-123→ Approve Team → HTTP 200{"success": false, "message": "Error creating GitHub repo: GitHub organization 'no-such-org-xyz-123' not found on GitHub — check …"}; no 500.github_org→ Approve Team →{"success": false, "message": "Error: this event has no GitHub organization set. Add it under Admin → …"}.🤖 Generated with Claude Code