-
Notifications
You must be signed in to change notification settings - Fork 26
FAQ
Common questions about Classroom 50, grouped by topic. For error messages and fixes, see Troubleshooting; for terms, see the Glossary.
You need a GitHub organization on the Team or Enterprise plan. Verified educators get GitHub Team free through GitHub Education, which unlocks everything Classroom 50 relies on (notably GitHub Pages from a private repo). Free/personal organizations can't host a classroom.
The teaching model is familiar — you create assignments (optionally with
starter code), students accept to get their own repository, and submissions are
auto-graded — but Classroom 50 has no server or database of its own. Your
classroom settings, roster, assignments, and scores are stored in a private
classroom50 repository in your organization, and grading runs in GitHub
Actions. See How Classroom 50 Works for the full
model, or the Glossary for the core concepts.
Both, and they're alternatives, not supplements. Teachers can do
everything from classroom50.org or from the
gh teacher CLI; students can accept and submit from either. Use whichever you
prefer. See the Web Teacher Guide or
CLI Teacher Guide.
There's no server to host. Classroom 50 runs entirely on GitHub's infrastructure and public APIs. The web app is a static, open-source site, so you're welcome to host your own copy. It only integrates with GitHub, not with self-hosted Git platforms.
Yes. A classroom is a directory in your organization's classroom50
repository, and an organization can hold as many as you like, for example one per
course, section, or term. Add each with Create classroom in the web app or
gh teacher classroom add.
You don't have to: one organization can hold many classrooms, so a stable teaching team usually keeps one organization with a classroom per term or section. Separate organizations fit school-wide adoption or very large courses. See One organization or several? for how to choose.
Yes. Classroom 50 has four roles: teacher (organization owner, full
control), head TA (write access to the classroom50 repository, not an
owner), TA (read-only access to the classroom50 repository), and
student. Manage staff in the web app under a classroom's
Settings → Staff and roles, or with gh teacher staff add. See the
Glossary for what each role can do.
Not on their own — GitHub requires an organization owner to invite members. Add students to the roster (by username, by email, or by bulk CSV upload), which sends the organization invitation. Once they've joined the organization, the assignment accept links work without any further action from you.
Yes. In the web app, use Upload with a roster CSV or a plain text list. A
row can identify a student by github_id, GitHub username, or email
address, so one file can mix students whose handle you know with ones you
only have an address for. Each address goes onto the roster right away as a
pending row, and is matched to the student's GitHub account when they accept.
From the CLI, invite one address with
gh teacher roster invite cs50-fall-2026 cs-principles ada@example.edu, or a
whole list with --file, a plaintext file holding one address per line. Only the
web app can invite staff by email; gh teacher roster invite always sends a
student invitation. gh teacher roster import adds and invites every student a
stored roster.csv identifies by username, but it never sends an email
invitation: on an email-only row it updates only the name and section, leaving the
invitation alone. See
Invitations by email and
Roster CSV fields.
Yes. The submissions view lists every rostered student, not only those who accepted, with their status — so you can see at a glance who hasn't started. Students you invited by email appear too, listed by address until they accept, though only organization owners see them: GitHub keeps pending invitations owner-only, so a TA's view leaves them out.
They're separate actions, on purpose:
- Unenroll removes the student from the classroom roster and team. It does not remove them from the organization and does not delete their assignment repositories.
- Remove from the organization revokes their access to every repo (including their assignment repos) but still doesn't delete anything.
- Deleting a repository is always a separate, manual step.
Yes, if the template lives inside your organization — registering the assignment grants the classroom's team read access to it. A private template outside your organization can't be shared with students; a public one works from anywhere. See Template visibility, including why a private template added to an existing assignment can 404 on accept.
Yes, for a templated assignment. Turn on Use the template's pull request
template as the Feedback PR body and Classroom 50 uses your template
repository's own pull request template (.github/pull_request_template.md,
pull_request_template.md, or docs/pull_request_template.md) as each
student's Feedback PR body instead of the built-in text. The assignment form
auto-checks this when it detects such a file, and you can toggle it off.
Note this is not GitHub's native behavior. GitHub only fills a
pull_request_template.md into pull requests opened through the web "compare
and pull request" flow, never for the API-created Feedback PR, so dropping the
file in alone does nothing until you enable this option. If the file is missing
or can't be read, the built-in body is used. It's set in the web app; there is
no gh teacher flag for it.
Yes. Due dates support a date and time (down to the second, in your timezone). Submissions after the due date are marked late; nothing is blocked automatically.
No — there is no cutoff date; the due date only marks later submissions late. To actually end an assignment, use Close submission, which blocks new accepts and sets every student's repository to read-only. See Due dates mark late; closing enforces.
Both start from no template; the difference is what (if anything) is committed:
- Template-less with a README (Add a README on): students get a repo with an initial commit and the autograder setup — good for write-from-scratch or short-answer work.
- Empty repository (Add a README off, built-in autograder off): a completely bare repo with no commit at all — no starter files and no autograding or feedback pull request, ever. Use it when students build everything themselves, including their own GitHub Actions.
- (Add a README off with the built-in autograder on is a third, in-between shape: an initialized repo carrying only the control files, no README, which grades normally.)
These repository-shape choices can be changed after creation, but a change only affects repositories accepted from then on — repositories students already accepted aren't retrofitted, so they keep their original shape. The web edit form asks you to confirm when students have already accepted. (Assignment type — Individual or Group — is the exception and stays locked, since switching it would invalidate existing submissions.) For every shape in one table, see Repository shapes.
Choose Group when creating the assignment and set a maximum group size. The first teammate to accept creates the shared repository and becomes its owner (the "founder"); they then invite the other teammates as collaborators. Everyone on the roster who is a collaborator gets the same score. Group repositories are named after the founder's username; custom group names aren't supported, and renaming a group repository isn't recommended.
The description is stored with the assignment, but student-facing instructions
are best placed in the template's README.md — that's what students see when
they open their repository. See Assignment Templates.
Yes. Use declarative tests (input/output, run-command, or pytest checks)
defined right on the assignment. No grading script needed. For more control,
write an autograder.py. See Autograding Basics
and Advanced Autograding.
Yes. Grade only on explicit submits (Submission type: A tagged commit), skip the built-in autograder for assignments graded elsewhere, pause autograding per assignment or organization-wide, or grade on self-hosted runners. Managing Actions cost covers every lever and what each one trades away.
Yes. Set runs-on in the assignment's runtime to your self-hosted labels (for
example ["self-hosted", "gpu"]). Self-hosted runners keep their own
toolchains, so Classroom 50 skips managed toolchain setup on them — provision
what your assignments need in the runner image. See
Autograders.
Yes. Each submission's Release and the Actions run summary include a per-test
breakdown (expected against actual output for I/O tests, captured stderr). A custom
autograder.py can add its own diagnostic messages to result.json.
If Codespaces is enabled for your organization, students can open their assignment repository in Codespaces like any other repo. Classroom 50 doesn't manage Codespaces itself — any education Codespaces benefit is handled on GitHub's side.
A few common reasons:
- Scores haven't been collected yet. Collection runs nightly; click Sync now on the submissions page to pull this assignment's latest results immediately (the sync is scoped to the assignment you're viewing, so it's fast even in a big classroom).
- GitHub Pages is still deploying. Right after a config change, published files can take a few minutes to go live.
- The student's repo predates a workflow update. If you updated Classroom 50 after they accepted, have them re-accept (or re-create the repo) to pick up the current setup.
See Troubleshooting for specific error messages.
Not yet. Scores live in each student's repository: every graded submission publishes a Release with the score and a per-test breakdown, which is what the student-facing View grade link opens. Showing scores inside the app is blocked by a technical limitation — Classroom 50 has no server, and the browser can't read Release assets cross-origin — but it's on the wish list (see #567). Point students at their repository's Releases page (or the Feedback PR) for results.
Yes, right in the web app — for both manual and autograded assignments. On the submissions page, each row's score cell has an edit button that opens a score-override dialog:
- Manual assignments — enter a score out of the assignment's Max points.
- Autograded assignments — enter a score to override the autograded result. The original autograded score is preserved; clearing the override restores it. If the submission hasn't been autograded yet, the dialog also asks for the max points to grade out of.
Overridden scores show a Manual badge and aren't changed by autograding until you clear the override. Use Clear override in the dialog to revert.
This editor appears only for organization owners (writing a score writes the
classroom50 repository). Under the hood, an override is an entry in the classroom's
scores.json with "override": true, which collection leaves untouched on
future runs — so you can still edit it by hand if you prefer (see
Collect scores).
Download scores as a CSV from the submissions page
(Download scores (CSV)). For the work itself, Download all submissions
in the same Actions menu bundles every repository's latest submission into
a single zip (built in your browser). For real clones, to run your own
tooling locally, gh teacher download clones every submission repository and also
writes a scores.csv summary at the destination root. The raw score data also
lives in scores.json in your classroom50 repository, so you can build your own
automations against it. The column-by-column reference for both CSVs is in
Score exports in Autograding Basics.
You can — Classroom 50 doesn't currently disallow one account holding both a
staff and a student role. Add yourself to the roster with gh teacher roster add (or the web app) while remaining on a staff team; you'll then show both
roles and be graded as a student. For how the app behaves with a dual-role
account, see
Staff who are also students.
One caveat: as an organization owner you keep admin on your own assignment
repo (GitHub won't let an owner reduce their own access to write), so it won't
match a real student's write-level setup. To test the exact student
experience, use a separate GitHub account added to the classroom as a
student.
Yes. gh teacher classroom migrate imports a GitHub Classroom into your
classroom50 repository — it copies each starter repo into your organization
as a fresh template and recreates the assignments. Rosters, scores, and past
student repositories are not migrated; you re-onboard students for the new
term. See gh teacher classroom migrate, and
Coming from GitHub Classroom? for how
GitHub Classroom's vocabulary (cutoff date, Download grades, roster
identifiers, teams) maps onto Classroom 50's.
Likely yes. As with GitHub Classroom, each student gets a normal GitHub
repository named <classroom>-<assignment>-<username>, so scripts that automate
git operations against those repos generally carry over.
Classroom 50 authenticates the same way the GitHub CLI does, using GitHub's
repo scope. That scope is all-or-nothing — GitHub provides no way to limit it
to a single organization's repositories — so the grant covers your repos even
though Classroom 50 only acts on classroom ones. This matches the CLI's
behavior. For what every scope grants and why, see
Permissions and access;
if you want to grant less, a fine-grained token scoped to one organization is
the tighter path (see
Reducing what you grant).
Yes. Sign-in requests one scope set for everyone, on purpose: one person can be both a teacher and a student (a teacher testing an assignment, a TA who also takes the course), so Classroom 50 never asks you to declare a role at sign-in. What you can do is decided afterward by your role in the organization and classroom, not by your token — a student's grant is broader than what a student actually uses (they never exercise the organization-administration or repository-deletion powers). To grant less than the default, sign in with a fine-grained token scoped to one organization. Why per-organization classic sign-in and separate teacher/student profiles aren't offered is recorded in Known Limitations.
Signing in does not request permission to delete repositories. One feature needs it: Tear down organization, which resets an organization by deleting every repository in it, and only after you type an explicit confirmation. When you use it, Classroom 50 asks you to request that permission and sign in again. Nothing else ever deletes a repository. See the full explanation in GitHub Integration.
It's not recommended. Some state is derived from both the config files and the
live state on GitHub.com, and the app updates the files automatically to keep
them in sync; a hand-edit can create a state the
tools don't know how to handle (and makes problems much harder to
troubleshoot). Manage the classroom through the web app or the gh teacher
CLI instead; the one documented exception is a scores.json score override
(see above).
The service token is a fine-grained personal access token stored as a secret
in your classroom50 repository; the score-collection, regrade, and token-probe
workflows use it. It's the
same token whether you set it up through the web app or the CLI — you only
need one per organization. See
the service-token setup.
Some capabilities from GitHub Classroom aren't available today, including LTI / LMS grade passback, in-app score visibility for students, and roster self-selection. See Requested, but architecturally hard in Known limitations for why, and share your use case in Discussions.
- Start here
- Teacher guides
- Autograding
- Students
- Reference