zed-industries/zed · error · RuntimeError
Project #{project_number} not found in {REPO_OWNER}
Error message
Project #{project_number} not found in {REPO_OWNER} What it means
load_project queries organization(login: REPO_OWNER).projectV2(number: project_number); GitHub returns null — not a body error — when no such project exists under that org or when the token cannot see it, and the script converts that null into this RuntimeError. Not-found and no-permission are indistinguishable at this call site.
Source
Thrown at script/github-guild-board.py:255
query($owner: String!, $number: Int!) {
organization(login: $owner) {
projectV2(number: $number) {
id
fields(first: 50) {
nodes {
... on ProjectV2Field { id name dataType }
... on ProjectV2SingleSelectField { id name options { id name } }
}
}
}
}
}
""",
{"owner": REPO_OWNER, "number": project_number},
)
project = data["organization"]["projectV2"]
if not project:
raise RuntimeError(f"Project #{project_number} not found in {REPO_OWNER}")
return project
def find_project_item(project_id, content_node_id):
# Includes each item's single-select values so callers can read Status
# without a second query.
data = github_graphql(
"""
query($contentId: ID!) {
node(id: $contentId) {
... on Issue {
projectItems(first: 50) {
nodes {
id
project { id }
fieldValues(first: 20) {
nodes {
... on ProjectV2ItemFieldSingleSelectValue {View on GitHub (pinned to bc538def45)
Solutions
- Confirm the number from the board URL: github.com/orgs/<org>/projects/<number>
- Check the token grants read:project (classic scope) or fine-grained project read on that org
- If the project is user-owned, query user(login:){ projectV2(...) } instead of organization(...)
- Verify REPO_OWNER matches the org that actually owns the project
Example fix
// before
project = data["organization"]["projectV2"]
if not project:
raise RuntimeError(f"Project #{project_number} not found in {REPO_OWNER}")
// after
project = data["organization"]["projectV2"]
if not project:
raise RuntimeError(
f"Project #{project_number} not found in {REPO_OWNER}; "
"check PROJECT_NUMBER, REPO_OWNER, and that the token has read:project"
) Defensive patterns
Strategy: validation
Validate before calling
def project_number_is_plausible(number: int) -> bool:
return isinstance(number, int) and number > 0 Type guard
def projectv2_visible(data: dict) -> bool:
org = data.get("organization") or {}
return bool(org.get("projectV2")) Try / catch
try:
project = load_project(project_number)
except RuntimeError as exc:
if "not found" in str(exc):
raise SystemExit(f"Check PROJECT_NUMBER={project_number}, REPO_OWNER={REPO_OWNER}, and token project scope")
raise Prevention
- Pin the project number via CI variables and alert when the board is recreated
- Grant tokens read:project explicitly
- Distinguish org-level from user-level projects before scripting
- Fail fast on null projectV2 instead of proceeding with None
When it happens
Trigger: PROJECT_NUMBER is wrong or belongs to a user-level project rather than an org project; GITHUB_TOKEN lacks read:project scope; the project is private to another org; REPO_OWNER env var is misspelled so the organization lookup resolves to null projectV2.
Common situations: Project deleted and recreated with a new number; CI token rotated without project scopes; workflow pointed at a fork or different org; project moved from org to user ownership.
Related errors
- project #{project_number} not found
- GraphQL errors: {json.dumps(data['errors'])[:300]}
- GraphQL error: {result['errors']}
- Field '{field_name}' not found on project. Available: {avail
- Option '{option_name}' not found in field '{field_name}'. Av
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/d40447aecac2e703.
Report an issue: GitHub.