tinyhumansai/openhuman · error · Error
Could not reach
Error message
Could not reach ${upserted.label}: ${msg} What it means
Quick-add provider flow in AIPanel: after upserting the cloud provider and persisting its key, the panel probes the provider's /models endpoint; if the probe fails it first rolls back (re-flushes the prior provider wire list and clears the stored key with clearCloudProviderKey so no key is orphaned on disk, #5339) and then throws 'Could not reach <label>: <msg>' with the probe's own message appended. Unlike the dialog path (error 170) there is no skip-verification escape hatch here.
Solutions
- Verify the exact endpoint with curl - e.g. curl -H 'Authorization: Bearer <key>' <endpoint>/models - and fix URL or key accordingly
- Re-enter and re-save the provider: rollback already removed it and cleared the key, so the previous state is restored
- Check the console.warn '[ai-settings] provider /models probe failed' entry for the underlying msg
- For local runtimes confirm the server is actually listening on that port before saving
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight the same request the panel will probe
async function providerReachable(endpoint: string, key: string): Promise<boolean> {
try {
const res = await fetch(`${endpoint.replace(/\/$/, '')}/models`, {
headers: { Authorization: `Bearer ${key}` },
});
return res.ok;
} catch {
return false;
}
} Try / catch
// the throw happens after rollback - catch it, then let the user re-enter config
catch (err) {
const msg = err instanceof Error ? err.message : String(err);
if (msg.startsWith('Could not reach')) {
// provider + key were rolled back; reopen the form pre-filled for correction
setProviderSaveNotice({ slug, kind: 'probe-failed', message: msg });
}
} Prevention
- curl the provider's /models with the key before saving - the panel probes exactly that
- Assume the save is transactional: on probe failure the provider and key are rolled back, so fix and re-submit
- For local model servers, confirm the process is listening before adding the provider
When it happens
Trigger: Saving a provider whose /models probe rejects: wrong endpoint URL, invalid or expired API key, DNS/firewall block, provider reachable only behind a VPN, or a self-signed certificate failing TLS validation.
Common situations: Typo'd base URL (missing /v1, wrong region subdomain); key pasted with a trailing newline or from the wrong service; local gateways (Ollama/LM Studio) not running at save time; corporate proxies intercepting the probe.
Related errors
- Endpoint must start with http:// or https://
- settings.ai.slugMissingError|settings.ai.slugInUseError|sett…
- Composio action listing failed on v3
- Failed to atomically replace config file
- manifest fetch failed
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/a7817337c1880a3d.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/components/settings/panels/AIPanel.tsx:3105
message: describeProviderVerificationFailure(slug, msg, t),
});
} else {
// Auth failure (wrong key), or a local runtime that isn't up:
// roll both stores back and reject so the user fixes it. Rollback
// failures are LOGGED, never swallowed — a silently failed
// key-clear is exactly what orphans a key on disk (#5339).
await flushCloudProviders(priorWireProviders).catch(rollbackErr =>
console.warn(`[ai-settings] rollback flush failed slug=${slug}`, rollbackErr)
);
if (isKeyProvider) {
await clearCloudProviderKey(slug).catch(rollbackErr =>
console.warn(
`[ai-settings] rollback clearCloudProviderKey failed slug=${slug}`,
rollbackErr
)
);
}
throw new Error(`Could not reach ${upserted.label}: ${msg}`);
}
}
}
}
const nextDraft = {
...draft,
cloudProviders: [...draft.cloudProviders.filter(p => p.slug !== slug), upserted],
};
await persist(nextDraft);
if (isCodexOAuth && slug === 'openai') {
await clearCloudProviderKey(slug);
}
if (slug === 'openai') {
setCodexAuthError(null);
}
setKeyDialogFor(null);
setPendingLocalLabel(null);View on GitHub (pinned to 7491200858)