tinyhumansai/openhuman · warning
secret request {} timed out after {}s
Error message
secret request {} timed out after {}s What it means
Same wait as the cancelled variant, but the full REQUEST_TIMEOUT (300 s / 5 minutes) elapsed without the user submitting the secret. The entry is explicitly forgotten via forget(r) on this path, so retrying the same SecretRef cannot succeed — a new request must be minted. This is a user-absence condition, not a system fault.
Source
Thrown at src/openhuman/mcp/registry/setup.rs:159
}
tracing::debug!("[mcp-setup] fulfilled ref={}", r.as_str());
true
}
/// Block on a freshly-minted request with the global timeout. On timeout
/// the entry is removed and `Err(_)` is returned.
pub async fn await_fulfillment(r: &SecretRef, rx: oneshot::Receiver<()>) -> anyhow::Result<()> {
match timeout(REQUEST_TIMEOUT, rx).await {
Ok(Ok(())) => Ok(()),
Ok(Err(_)) => {
// Sender dropped — usually means GC purged the entry. Surface
// as a timeout-style error to keep the caller simple.
let _ = forget(r).await;
anyhow::bail!("secret request {} cancelled before user submit", r.as_str())
}
Err(_) => {
let _ = forget(r).await;
anyhow::bail!(
"secret request {} timed out after {}s",
r.as_str(),
REQUEST_TIMEOUT.as_secs()
)
}
}
}
/// Resolve a `{KEY: SecretRef}` map into a `Vec<(KEY, VALUE)>`. Returns
/// `Err(_)` if any ref is unknown or not yet fulfilled — callers should
/// retry rather than partially-apply.
///
/// Touches the `last_touched` on every hit so iterative `test_connection`
/// calls reset the idle TTL.
pub async fn resolve_refs(
refs: &HashMap<String, SecretRef>,
) -> anyhow::Result<Vec<(String, String)>> {
let mut guard = map().lock().await;View on GitHub (pinned to 7491200858)
Solutions
- Re-run the install in an interactive session and submit the secret within the 5-minute window.
- For unattended flows, pre-provision the values (e.g. via the mcp_client_env path used at consume time) instead of relying on the interactive request.
- If the prompt never appeared, check the frontend dialog wiring before retrying — the timeout will just repeat.
Defensive patterns
Strategy: retry
Try / catch
Branch on the message: `timed out after 300s` → mint a new request and re-prompt (the old SecretRef was forgotten via forget()); distinguish from `cancelled before user submit`, which indicates GC/supersession rather than user absence.
Prevention
- Submit secrets within the 5-minute REQUEST_TIMEOUT window.
- Pre-provision env values for unattended installs instead of the interactive path.
- Surface prompt age/deadline in the UI so users see the cutoff.
When it happens
Trigger: await_fulfillment waits the full 300 s while the user never submits: the prompt was left open and abandoned, an unattended/scripted install expected pre-provisioned env values, or the frontend failed to render the secret dialog at all.
Common situations: AFK user; headless run where an interactive secret prompt can never be answered; UI bug hiding the prompt; CI invoking install flows that require credentials.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- secret request {} cancelled before user submit
- Timed out waiting for browser sign-in. Try again.
- oauthAuthReadinessUserMessage(quick.reason)
- Socket not connected
- Invalid ${paramName}: ${value}. Must be a positive integer.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/b2e9ace87e7e338d.
Report an issue: GitHub.