fix(deps): addIssueDependency sends {index} without owner/repo — 404 #213

Closed
opened 2026-04-21 10:31:28 +00:00 by claude-desktop · 0 comments
Collaborator

Bug

apps/server/src/forgejo-api.ts::addIssueDependency posts {index: N} as the body, but Forgejo's native /repos/{repo}/issues/{N}/dependencies endpoint requires {owner, repo, index}. With only {index}, Forgejo returns 404 IsErrRepoNotExist — the API tries to look up the blocker's repo from the body fields and fails because owner_name is empty.

Discovered while running just deps-backfill charles/claude-hooks on 2026-04-21 against freshly-created issues #208–#212. All three body-parsed edges failed silently (created=0 failed=3).

Repro

TOKEN=$(cat ~/.config/claude-hooks/tokens/boss)
# Broken payload (what the service sends today):
curl -X POST https://forge.jacquin.app/api/v1/repos/charles/claude-hooks/issues/209/dependencies \
  -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
  -d '{"index":208}'
# → 404 IsErrRepoNotExist "owner_name: , name: "

# Correct payload:
curl -X POST https://forge.jacquin.app/api/v1/repos/charles/claude-hooks/issues/209/dependencies \
  -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
  -d '{"owner":"charles","repo":"claude-hooks","index":208}'
# → 201 Created

Acceptance criteria

  • apps/server/src/forgejo-api.ts::addIssueDependency splits repo as <owner>/<name> and sends {owner, repo: name, index: blockerNumber} in the POST body.
  • Same fix applied to any sibling helper that hits /dependencies (check removeIssueDependency / /blocks endpoints — Forgejo uses the same meta-payload convention for all issue-edge mutations).
  • Unit test in apps/server/src/deps.test.ts (or a new forgejo-api.test.ts) covers the payload shape — bun:test's mock() on fetch is enough; assert the body JSON includes owner + repo.
  • just deps-backfill charles/claude-hooks reruns clean (idempotent — Forgejo returns 201 once, then 200/409 on retries).
  • On-wire verification: the three edges that deps-backfill failed to create on 2026-04-21 are in place — wired manually via curl as a stopgap, so this ticket is purely the code fix + regression test.

Out of scope

  • Rewriting the backfill output format / CLI UX.
  • Adding retries or exponential backoff on the single-edge failure path.

References

  • apps/server/src/forgejo-api.ts:399-418 — broken payload.
  • apps/server/src/deps.ts:710-736 — backfill orchestrator (unchanged, just calls the fixed helper).
  • Forgejo Swagger: POST /repos/{owner}/{repo}/issues/{index}/dependencies — the IssueMeta body schema.
## Bug `apps/server/src/forgejo-api.ts::addIssueDependency` posts `{index: N}` as the body, but Forgejo's native `/repos/{repo}/issues/{N}/dependencies` endpoint requires `{owner, repo, index}`. With only `{index}`, Forgejo returns `404 IsErrRepoNotExist` — the API tries to look up the blocker's repo from the body fields and fails because `owner_name` is empty. Discovered while running `just deps-backfill charles/claude-hooks` on 2026-04-21 against freshly-created issues #208–#212. All three body-parsed edges failed silently (`created=0 failed=3`). ## Repro ```bash TOKEN=$(cat ~/.config/claude-hooks/tokens/boss) # Broken payload (what the service sends today): curl -X POST https://forge.jacquin.app/api/v1/repos/charles/claude-hooks/issues/209/dependencies \ -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \ -d '{"index":208}' # → 404 IsErrRepoNotExist "owner_name: , name: " # Correct payload: curl -X POST https://forge.jacquin.app/api/v1/repos/charles/claude-hooks/issues/209/dependencies \ -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \ -d '{"owner":"charles","repo":"claude-hooks","index":208}' # → 201 Created ``` ## Acceptance criteria - [ ] `apps/server/src/forgejo-api.ts::addIssueDependency` splits `repo` as `<owner>/<name>` and sends `{owner, repo: name, index: blockerNumber}` in the POST body. - [ ] Same fix applied to any sibling helper that hits `/dependencies` (check `removeIssueDependency` / `/blocks` endpoints — Forgejo uses the same meta-payload convention for all issue-edge mutations). - [ ] Unit test in `apps/server/src/deps.test.ts` (or a new `forgejo-api.test.ts`) covers the payload shape — bun:test's `mock()` on `fetch` is enough; assert the body JSON includes `owner` + `repo`. - [ ] `just deps-backfill charles/claude-hooks` reruns clean (idempotent — Forgejo returns 201 once, then 200/409 on retries). - [ ] On-wire verification: the three edges that `deps-backfill` failed to create on 2026-04-21 are in place — wired manually via curl as a stopgap, so this ticket is purely the code fix + regression test. ## Out of scope - Rewriting the backfill output format / CLI UX. - Adding retries or exponential backoff on the single-edge failure path. ## References - `apps/server/src/forgejo-api.ts:399-418` — broken payload. - `apps/server/src/deps.ts:710-736` — backfill orchestrator (unchanged, just calls the fixed helper). - Forgejo Swagger: `POST /repos/{owner}/{repo}/issues/{index}/dependencies` — the `IssueMeta` body schema.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#213
No description provided.