tinyhumansai/openhuman · error
Could not reach ${upserted.label}: ${msg}
Error message
Could not reach ${upserted.label}: ${msg} What it means
When saving a provider whose runtime requires a /models probe, a failed probe first triggers rollback (re-flush the previous provider wire list and clear the just-written key so nothing is orphaned on disk, cf. #5339) and then throws this error embedding the probe's own failure message.
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 a221052e0d)
Solutions
- Fix the underlying probe error shown after the colon (auth → new key; network → correct URL/proxy)
- Confirm the endpoint is an OpenAI-compatible base that serves GET /models
- Save again only after the endpoint verifiably works — the failed attempt already rolled back, so no orphaned key remains
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight the probe with the entered values before saving:
const ok = await fetch(`${endpoint}/models`, {
headers: { Authorization: `Bearer ${apiKey}` },
}).then(r => r.ok);
if (!ok) { /* block save; show reason */ } Type guard
const isProbeFailure = (msg: string): boolean => msg.startsWith('Could not reach'); Try / catch
try {
await saveProvider(cfg);
} catch (e) {
if (e instanceof Error && isProbeFailure(e.message)) {
// rollback already ran: fix key/URL from the embedded probe message and retry
return;
}
throw e;
} Prevention
- curl the provider's /models with the key before saving
- Confirm the endpoint is an OpenAI-compatible base URL
- Trust the rollback: after this error no partial provider/key is left behind — just fix and re-save
When it happens
Trigger: Endpoint unreachable (wrong URL/port), API key rejected (401/403), TLS/proxy failure, or a server returning non-OpenAI JSON — all during the save-time /models fetch.
Common situations: Typo'd base URL; key without quota or permission; self-signed certificate behind a corporate proxy; endpoint that is not actually OpenAI-compatible.
Related errors
- Endpoint must start with http:// or https://
- Failed to send magic link (${response.status})
- Request timed out. Please try again.
- HTTP error! status: ${response.status}
- [transport:cloud] ${method} timed out after ${this.timeoutMs
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/a7817337c1880a3d.
Report an issue: GitHub.