jdx/mise · error
relay request timeout must be greater than zero
Error message
relay request timeout must be greater than zero
What it means
configure parses settings.github_relay.request_timeout (via duration::parse_duration) and bails if the resulting Duration is zero. A zero timeout would make every relay request fail immediately, so it is rejected as configuration error. Note the error is about the configured value, not a CLI flag here.
Solutions
- Set github_relay.request_timeout to a positive duration, e.g. "30s"
- Ensure the value includes a valid unit (duration::parse_duration input) and is non-zero
- Remove the override to fall back to the built-in default timeout
Example fix
// before [github_relay] request_timeout = "0s" // after [github_relay] request_timeout = "30s"
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the configured timeout parses and is non-zero let t = humantime::parse_duration(&settings.github_relay.request_timeout)?; assert!(!t.is_zero(), "request_timeout must be > 0, e.g. 30s");
Try / catch
match err {
RelayConfigError::ZeroTimeout => eprintln!("set github_relay.request_timeout to a positive duration like 30s"),
e => return Err(e),
} Prevention
- Never set timeouts to 0 as a 'disable' trick — use a large positive value instead
- Include explicit units in duration strings
- Add config validation in CI
- Keep sane defaults; only override when necessary
When it happens
Trigger: configure runs and settings.github_relay.request_timeout parses to 0 — e.g. request_timeout = "0s", "0", or "0ms" in the config.
Common situations: Someone 'disabling' the timeout by setting it to zero; a templated config defaulting to 0; editing config values without understanding units.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- relay log format must be text or jsonl
- Check timeout must be greater than zero
- --connect-timeout must be greater than zero
- encrypt an external dotfile source instead of configuration
- relay concurrency must be between 1 and 32
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/1e0c3f0799c25518.
Report an issue: GitHub.
Appendix: source
Thrown at src/github_relay.rs:98
no_log_requests: bool,
format: Option<&str>,
max_duration: Option<&str>,
) -> Result<Option<Scope>> {
let Some(scope) = scope else {
if log_requests || no_log_requests || format.is_some() || max_duration.is_some() {
bail!("relay options require --github-relay-read-only");
}
return Ok(None);
};
let settings = crate::config::Settings::get();
let settings = &settings.github_relay;
let format = format.unwrap_or(&settings.log_format);
if !matches!(format, "text" | "jsonl") {
bail!("relay log format must be text or jsonl");
}
let timeout = duration::parse_duration(&settings.request_timeout)?;
if timeout.is_zero() {
bail!("relay request timeout must be greater than zero");
}
if !(1..=32).contains(&settings.concurrency) {
bail!("relay concurrency must be between 1 and 32");
}
let max_duration = duration::parse_duration(max_duration.unwrap_or(&settings.max_duration))?;
if std::time::Instant::now().checked_add(timeout).is_none()
|| std::time::Instant::now()
.checked_add(max_duration)
.is_none()
{
bail!("relay duration is too large");
}
#[cfg(not(unix))]
let _ = max_duration;
#[cfg(unix)]
let scope = {
let mut scope = scope;
scope.options = Options {View on GitHub (pinned to 533346cc37)