fix(api): reject a non-positive-integer installation id on the seven id routes - #9740
Conversation
…id routes
Seven routes parsed an installation id and validated it with Number.isFinite
alone, which accepts fractions and exponent notation -- Number("1.5") -> 1.5 and
0/negative all passed and were bound straight into the D1 lookup. A GitHub
installation id is always a positive integer, and the repo's own sibling routes
(the dead-letter-queue admin routes, the chat-qa :number param) already guard with
!Number.isInteger(id) || id <= 0.
Switch all seven -- GET/`/v1/installations/:id/{health,repair}`,
POST `.../repair/refresh`, and their four `/v1/app/installations/:id/*` siblings
(health, repair, repair/refresh, agent/bulk-settings) -- to that guard, returning
the existing { error: "invalid_installation_id" } body with 400 unchanged. The two
`/v1/internal/orb/*` routes that parse installationId from a JSON body are out of
scope and untouched.
Every one of the seven operations now declares 400 in the published OpenAPI
document (the four app routes in orb-and-control-route-specs.ts, the three legacy
routes' registerPath blocks in spec.ts); bulk-settings' existing 400 description is
widened to cover the id cause too. openapi.json is regenerated.
Adds a test asserting each of the seven routes rejects a fractional/zero/negative
id with 400 invalid_installation_id, while a valid positive integer still reaches
the handler.
Closes JSONbored#9716
|
🚨 Contributor flagged. Click here for more info: Superagent Dashboard |
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-29 05:52:27 UTC
Review summary Nits — 3 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Decision record
Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. Scroll preview
A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
Superagent did not find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9740 +/- ##
===========================================
- Coverage 90.27% 77.46% -12.81%
===========================================
Files 904 285 -619
Lines 113176 62234 -50942
Branches 26839 7354 -19485
===========================================
- Hits 102170 48210 -53960
- Misses 9676 13651 +3975
+ Partials 1330 373 -957
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Held for manual review: the gate and required CI are green, but GitHub reports this pull request's mergeable state as |


What & why
Closes #9716.
Seven routes parsed an installation id out of the path and validated it with
Number.isFinitealone,which accepts fractions and exponent notation —
Number("1.5")→1.5, and0/negative all passedand were bound straight into the D1 lookup. A GitHub installation id is always a positive integer, and
the repo's own sibling routes already guard with
!Number.isInteger(id) || id <= 0(thedead-letter-queue admin routes at
routes.ts:2031/:2057, and the chat-qa:numberparam). A clientsending a malformed id also got an undocumented status.
Change
GET /v1/installations/:id/{health,repair},POST .../repair/refresh, and thefour
/v1/app/installations/:id/*siblings (health, repair, repair/refresh, agent/bulk-settings) —now use
!Number.isInteger(installationId) || installationId <= 0, returning the existing{ error: "invalid_installation_id" }body with400unchanged. The two/v1/internal/orb/*routesthat parse
installationIdfrom a JSON body are out of scope and untouched.400in the published OpenAPI document (the four approutes in
orb-and-control-route-specs.ts, the three legacyregisterPathblocks inspec.ts);bulk-settings' existing400description is widened to cover the id cause too.openapi.jsonisregenerated.
Validation
1.5), zero, and negative id with400 invalid_installation_id, while a valid positive integer still reaches the handler (200).(
1e3→1000is a genuine integer and is deliberately still accepted.)Number.isFinitefails the new test.ui:openapi:checkdrift-check clean.