can1357/oh-my-pi · error · HTTPException
workspace_key does not match repo
Error message
workspace_key does not match repo
What it means
The `git_push_endpoint` validates that the caller-supplied `workspace_key` starts with `<owner>__<repo>__` — the naming scheme the proxy uses to bind workspaces to repositories. If the key does not match the `repo` field in the same request, the proxy rejects it with HTTP 400 to prevent pushing a workspace's repo to a different GitHub target.
Source
Thrown at python/robomp/src/proxy/server.py:917
remote_url=remote.url,
auth_url=remote.auth_url,
)
except GitCommandError as exc:
return _git_error_response(exc)
return JSONResponse({"pool_dir": str(target)})
@app.post("/gh/v1/git/push")
async def git_push_endpoint(request: Request) -> JSONResponse:
data = await _json_body(request)
repo = _require_str(data.get("repo"), "repo")
workspace_key = _require_str(data.get("workspace_key"), "workspace_key")
branch = _require_branch(data.get("branch"))
expected_head = _require_str(data.get("expected_head"), "expected_head")
slot_uid = _optional_slot_uid(data.get("slot_uid"))
# Sanity-check workspace_key matches the repo claim.
expected_prefix = repo.replace("/", "__") + "__"
if not workspace_key.startswith(expected_prefix):
raise HTTPException(400, "workspace_key does not match repo")
repo_dir = _workspace_repo_dir(settings, workspace_key)
if not repo_dir.is_dir():
raise HTTPException(404, f"workspace not found: {workspace_key}")
remote = await asyncio.to_thread(
_origin_remote_auth,
repo_dir,
repo,
_resolve_token(settings),
push=True,
slot_uid=slot_uid,
)
try:
result = await _run_git_op(
git_push,
repo_dir,
branch=branch,
expected_head=expected_head,
token=remote.token,View on GitHub (pinned to 9690622007)
Solutions
- Use the workspace_key exactly as returned when the workspace was created, and set `repo` to the repo that workspace belongs to
- Check that `repo.replace('/', '__') + '__'` is a prefix of your workspace_key; fix whichever field is wrong
- If the repo was renamed/transferred, create a new workspace for the new repo identity
Example fix
// before
{ "repo": "owner/other-repo", "workspace_key": "owner__name__task1" }
// after
{ "repo": "owner/name", "workspace_key": "owner__name__task1" } Defensive patterns
Strategy: validation
Validate before calling
def check_workspace_matches(repo: str, workspace_key: str) -> None:
prefix = repo.replace("/", "__") + "__"
if not workspace_key.startswith(prefix):
raise ValueError(f"workspace_key {workspace_key!r} does not belong to repo {repo!r}")
check_workspace_matches(repo, workspace_key) Try / catch
try:
proxy.git_push(repo=repo, workspace_key=key, ...)
except HTTPError as e:
if e.response.status_code == 400 and "workspace_key does not match repo" in e.response.text:
raise ValueError(f"workspace {key} is not bound to {repo}; use the key returned at workspace creation") from e
raise Prevention
- Always take workspace_key from the workspace-creation response, never hand-build it
- Keep repo and workspace_key in one config object so they cannot drift apart
- Re-derive workspaces after repo renames/transfers
- Add a prefix check in client code before sending push requests
When it happens
Trigger: POSTing to /gh/v1/git/push with a `repo` like `owner/name` but a `workspace_key` that does not begin with `owner__name__` — e.g. a workspace key belonging to another repo, a typo'd repo field, or a hand-constructed workspace_key.
Common situations: Copy-pasting a workspace_key from one task/session into a push request for a different repo, renaming/moving the repo (owner transfer) while workspace keys keep the old prefix, or constructing keys manually instead of from the workspace creation response.
Related errors
- The current working directory is already the primary workspa
- invalid workspace_key {workspace_key!r}
- {str(exc)} (ManualTriageError)
- retry requires 'delivery_id' or 'issue'
- cancel requires 'delivery_id'
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5fb60274f7e11bb2.
Report an issue: GitHub.