I was recording a demo video. I had a GitHub project board with a tidy set of tickets on it, Repoker installed and authorized, and a dropdown that was supposed to list my boards. The dropdown was empty.
No error. No red text. Just an empty list where my project should have been, which is the most annoying kind of bug there is. If something had failed loudly I'd have known where to look. Instead I did what you'd do: assumed I'd fumbled a permission somewhere, and went back to the settings page to fix it.
I did not fix it, because there was nothing to fix. What I eventually worked out is that a GitHub App can read organization-owned Projects and cannot read user-owned ones, and no combination of checkboxes changes that. If you've been hunting for the permission that makes your personal Projects visible to your app, I can save you the couple of hours I spent: it isn't there.
The permission that doesn't exist
Here's the part that sends you in circles. Go to your GitHub App's settings and you'll find a Projects permission under Repository permissions. Excellent, you think. That's the one. You set it to read and write, reinstall, and nothing changes.
That checkbox governs the old repository-level project boards, not the ProjectsV2 boards that live at the account or organization level. Same word, different feature. So you keep looking, and you find another Projects permission under Organization permissions, which does control ProjectsV2. Set that one and your org boards work.
Then you go looking for the equivalent under account permissions, for the boards owned by you rather than an org. And you scroll. And it isn't there. There is no account-level Projects permission to grant.
That absence is the whole answer, but it reads like an oversight rather than a rule. I remember toggling things twice and reinstalling the app on my own account just to be sure I hadn't misread the page. Nothing. When a UI lacks the option you're looking for, your first instinct is that you're on the wrong screen, not that the capability doesn't exist.
What the API actually says
The GraphQL API is more direct about it, once you ask in a way that forces an answer.
Listing ProjectsV2 for an account is the same query either way. The only thing that changes is the root field, organization or user, chosen from the account type GitHub reports for each installation:
const owner = type === "Organization" ? "organization" : "user";
const query = `
query($login: String!, $after: String) {
${owner}(login: $login) {
projectsV2(first: 100, after: $after) {
pageInfo { hasNextPage endCursor }
nodes { id number title closed }
}
}
}`;
Point that at an org and you get your boards. Point the identical query at a user login, authenticated as an App, and GitHub answers:
Resource not accessible by integration
That string is the one people paste into search bars at eleven at night, and it's frustratingly generic. It shows up for all sorts of permission problems, which is exactly why it sends you back to the settings page for another round of checkbox roulette. In this case it doesn't mean "you forgot a permission." It means "this door doesn't open for apps."
Why mine failed silently
So the API does say something. Why was my dropdown just empty?
Because of a line I'd written myself a week or two earlier, for perfectly reasonable-sounding reasons. Repoker lists your projects by fanning out across every account where the app is installed and merging the results:
const lists = await Promise.all(
installations.map((i) =>
listProjectsForAccount(token, i.accountLogin, i.accountType).catch(() => []),
),
);
Look at that .catch(() => []). The intent was defensive: if one installation out of five has a problem, don't blow up the entire list and show the user nothing. Degrade gracefully. Return what you can.
Which is a good instinct, and it produced the worst possible outcome here. My personal account threw "Resource not accessible by integration," the catch swallowed it, and the fan-out cheerfully returned an empty array for that account. The merge succeeded. The endpoint returned 200. The UI rendered exactly what it was told: nothing.
Graceful degradation and silent failure are the same code path, distinguished only by whether you tell anyone. I'd written the first and shipped the second. The error was there the whole time, caught and dropped a few stack frames from a user who had no way to see it.
Fixing what I could actually fix
I couldn't make GitHub expose personal Projects. That part is closed. What I could fix is the twenty minutes a user would otherwise spend re-reading a permissions page looking for a checkbox that was never printed.
So the empty state stopped being empty. Anywhere Repoker can end up with no projects to show, it now says why, and says what to do instead:
No projects found. Repoker works with organization Projects. GitHub doesn't let apps access personal (user-owned) projects.
That text sits in the lobby when you create a room, in the project picker inside a room, and in the browser extension when it can't read the board attached to an issue. It's in the FAQ on the landing page too, because "can I use this with a personal project?" is a question people will ask before they ever install anything, and the honest answer up front is worth more than a support conversation later.
The extension gets the sharpest version, because that's where you're most likely to hit it mid-flow with a ticket already open:
Repoker can't read this issue's project. GitHub only exposes organization projects to apps, not personal (user-owned) ones. Move the board to an organization and install Repoker there.
Notice what each of those does. It names the constraint, it makes clear the constraint is GitHub's and not something the user misconfigured, and it gives them the one move that actually works. No apology, no vague "something went wrong," no invitation to go check their permissions again.
The workaround, plainly
If you're hitting this yourself, the fix is to move the board under an organization and install the app there. Free organizations exist, and you can create one and transfer a project into it in a few minutes. It feels like overkill for a solo project, and I understand the reluctance, but it's the only path that works today.
For teams it's usually moot, because the board is already org-owned. This bites hardest on exactly the people evaluating your tool for the first time, poking at it with a personal side project before they'd dream of installing it on the company org. Which is a rough audience to fail silently in front of.
What I took away
The platform limitation cost me a couple of hours. The silent failure cost me far more, and it was entirely mine.
I've started treating every catch that returns an empty value as a small decision about who gets to know. Sometimes swallowing really is right, and one flaky installation shouldn't nuke a list. But "the list is empty" and "we couldn't read this account" are different facts, and if you collapse them into the same empty dropdown, you've decided your user doesn't need the difference. They do. They're the one who has to act on it.
If you're building on the GitHub API and your Projects queries are coming back empty, check whether you're pointing at a user or an organization before you touch a single permission. And if you want to see the friendlier version of this failure in the wild, Repoker will tell you exactly what's wrong the first time, which is the least I could do after it told me nothing at all.