Summary
In wait_for_status, HTTP error responses (401, 429, 500) are not checked before JSON parsing. Parse failures from error bodies cause silent continue retries, so the function eventually returns Error::Timeout instead of the actual error.
Location
- File:
src/lib.rs
- Line(s): 247–269
Severity
High
Details
let body = resp.text().await.unwrap_or_default();
let parsed: ApiResp<StatusData> = match serde_json::from_str(&body) {
Ok(p) => p,
Err(e) => {
warn!("status JSON: {e}");
continue; // silently retries on 401, 429, 500...
}
};
A 401 Unauthorized (expired token) or 429 Too Many Requests loops until max_wait expires. The caller receives Timeout with no indication of the actual cause. submit_run and fetch_dataset_items both correctly check status.is_success() — this protection is missing only in wait_for_status.
Suggested Fix
Check HTTP status before parsing:
let status = resp.status();
let body = resp.text().await.unwrap_or_default();
if !status.is_success() {
return Err(Error::ApiStatus { status: status.as_u16(), body: body.chars().take(400).collect() });
}
Automated finding by repo-monitor
Summary
In
wait_for_status, HTTP error responses (401, 429, 500) are not checked before JSON parsing. Parse failures from error bodies cause silentcontinueretries, so the function eventually returnsError::Timeoutinstead of the actual error.Location
src/lib.rsSeverity
High
Details
A 401 Unauthorized (expired token) or 429 Too Many Requests loops until
max_waitexpires. The caller receivesTimeoutwith no indication of the actual cause.submit_runandfetch_dataset_itemsboth correctly checkstatus.is_success()— this protection is missing only inwait_for_status.Suggested Fix
Check HTTP status before parsing:
Automated finding by repo-monitor