Skip to content

fix: complete the malformed-input guards, including the two paths still live - #3663

Merged
Salazareo merged 1 commit into
mainfrom
DS/PUT-1618-followup
Aug 28, 2026
Merged

fix: complete the malformed-input guards, including the two paths still live#3663
Salazareo merged 1 commit into
mainfrom
DS/PUT-1618-followup

Conversation

@Salazareo

Copy link
Copy Markdown
Member

Review of the previous change found three of its claims unmet.

The image-generation crash it reported fixed is still reachable. The assert was scattered across three helpers, and Gemini and OpenAI call isHttpUrl directly on input_images without going through any of them — so two of seven providers still 500 on a non-string. isHttpUrl now refuses a non-string itself, and the shape is settled once in ImageGenerationDriver.generate, where the driver call arrives, rather than per helper. That also covers input_images that isn't an array, which produced a different crash per provider.

The sixth case in the ticket, previously unlocated, is Messages.js reading tool_call.function.name with no guard — reachable with {"messages":[{"role":"assistant","tool_calls":[{"id":"x"}]}]}. Guarded, along with the same shape in make_claude_tools: a TypeError there carries no status, so the retry loop reads it as a provider failure and marks the route unhealthy for every caller.

#hardExpiryFromExpiresIn returning null for a bad type moved the failure past the session INSERT, leaving an orphaned non-expiring row and still answering
500. Reverted; the controller guard is the fix, now covering fractions, negatives and unparseable durations rather than only wrong types.

Also: the batch write handlers check that the body is an array but not what is in it, so a null element 500s the same way; #requireObjectBody accepted an array despite its name; handleCreateAccessToken destructured a body that may be absent; and two AGPL notices had been rewrapped with a Markdown link.

…ll live

Review of the previous change found three of its claims unmet.

The image-generation crash it reported fixed is still reachable. The assert was
scattered across three helpers, and Gemini and OpenAI call `isHttpUrl` directly
on `input_images` without going through any of them — so two of seven providers
still 500 on a non-string. `isHttpUrl` now refuses a non-string itself, and the
shape is settled once in `ImageGenerationDriver.generate`, where the driver call
arrives, rather than per helper. That also covers `input_images` that isn't an
array, which produced a different crash per provider.

The sixth case in the ticket, previously unlocated, is
`Messages.js` reading `tool_call.function.name` with no guard — reachable with
`{"messages":[{"role":"assistant","tool_calls":[{"id":"x"}]}]}`. Guarded, along
with the same shape in `make_claude_tools`: a TypeError there carries no status,
so the retry loop reads it as a provider failure and marks the route unhealthy
for every caller.

`#hardExpiryFromExpiresIn` returning null for a bad type moved the failure past
the session INSERT, leaving an orphaned non-expiring row and still answering
500. Reverted; the controller guard is the fix, now covering fractions,
negatives and unparseable durations rather than only wrong types.

Also: the batch write handlers check that the body is an array but not what is
in it, so a null element 500s the same way; `#requireObjectBody` accepted an
array despite its name; `handleCreateAccessToken` destructured a body that may
be absent; and two AGPL notices had been rewrapped with a Markdown link.
@Salazareo
Salazareo merged commit 9fab474 into main Aug 28, 2026
4 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 93.72%
⬆️ +0.01%
24812 / 26474
🔵 Statements 91.98%
⬆️ +0.01%
26803 / 29137
🔵 Functions 89.97%
🟰 ±0%
4343 / 4827
🔵 Branches 80.62%
⬆️ +0.03%
18101 / 22450
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/backend/controllers/auth/AuthController.ts 90.77%
⬆️ +0.01%
79.23%
⬆️ +0.15%
77.77%
🟰 ±0%
91.72%
⬆️ +0.02%
6, 24-26, 32, 33, 34, 38-39, 44, 45, 47, 474-476, 490-492, 620-621, 695-697, 714-716, 858, 920-924, 942, 984-989, 998, 1009, 1024-1029, 1035, 1079-1080, 1083-1088, 1231, 1262-1263, 1282-1286, 1324-1326, 1328-1330, 1378, 1406-1417, 1492-1494, 1507, 1567-1569, 1603, 1616-1618, 1644-1646, 1677, 1681-1683, 1781, 1867, 1926, 1971, 2030, 2043-2046, 2088-2090, 2108-2111, 2165-2167, 2179-2181, 2197-2199, 2213-2216, 2222, 2241, 2252, 2373-2377, 2406, 2437-2439, 2451-2457, 2517-2522, 2596-2598, 2661, 2699, 2740-2742, 2808, 2838, 2917-2919, 2921-2923, 2927-2930, 2943-2946, 3011-3016, 3019-3021, 3048, 3067, 3085, 3103, 3116, 3139, 3151, 3168, 3178, 3189, 3243, 3376-3380, 3401-3403, 3417, 3420-3424, 3499
src/backend/controllers/fs/FSController.ts 91.93%
🟰 ±0%
76.49%
⬆️ +0.03%
91.47%
🟰 ±0%
93.39%
🟰 ±0%
6, 24-26, 32, 33, 34, 38-39, 44, 45, 47, 102-110, 307, 389, 427, 433, 438-445, 448, 479-483, 553-557, 577-581, 633-637, 702-704, 723-727, 940, 1207, 1208, 1209, 1225-1227, 1259, 1263, 1295-1297, 1310, 1314, 1322, 1373-1375, 1384-1386, 1392, 1410-1411, 1418-1419, 1430, 1454, 1470, 1474, 1478, 1501, 1564-1566, 1614, 1634-1637, 1642-1644, 1647-1650, 1704-1706, 1791, 1820, 1845, 1886-1890, 1893, 1896, 1940-1943, 1951, 2023-2027, 2080-2082, 2091-2099
src/backend/drivers/ai-chat/utils/FunctionCalling.js 100%
🟰 ±0%
94.44%
⬆️ +0.33%
100%
🟰 ±0%
100%
🟰 ±0%
src/backend/drivers/ai-chat/utils/Messages.js 99.03%
⬆️ +0.02%
93.1%
⬆️ +0.16%
100%
🟰 ±0%
100%
🟰 ±0%
207
src/backend/drivers/ai-image/ImageGenerationDriver.ts 91.62%
⬆️ +0.05%
79.57%
🟰 ±0%
94.44%
🟰 ±0%
91.12%
⬆️ +0.05%
112, 167, 170, 186-190, 358-368, 429-433, 441-445, 472, 475, 506-510
src/backend/drivers/ai-image/inputImage.ts 100%
🟰 ±0%
95.55%
⬆️ +1.44%
100%
🟰 ±0%
100%
🟰 ±0%
src/backend/services/auth/AuthService.ts 90.26%
⬆️ +0.13%
74.18%
⬆️ +0.17%
81.48%
🟰 ±0%
94.84%
⬆️ +0.18%
6, 9, 13, 16, 24-26, 32, 33, 34, 38-39, 44, 45, 47, 77, 81, 124-126, 155, 212-214, 246-248, 278, 404-407, 419, 571, 803-807, 816, 889, 891, 933, 950, 976, 1013, 1038, 1040, 1046, 1059-1061, 1088-1090, 1116-1120, 1156, 1171, 1194, 1207, 1209, 1227-1229
Generated in workflow #867 for commit 4cff803 by the Vitest Coverage Report Action

@Salazareo
Salazareo deleted the DS/PUT-1618-followup branch August 28, 2026 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant