fix(desktop): route gateway provider errors to onboarding

The "No inference provider configured" auth error reaches the renderer through gateway error events, not the prompt.submit promise; the previous patch only caught the latter, so the error toast still surfaced and onboarding never opened.

Also strip credential-shaped env vars from the test:desktop:fresh sandbox so the packaged backend can't see provider keys leaking from the launching shell.
This commit is contained in:
Brooklyn Nicholson 2026-05-07 23:02:34 -04:00
parent c730a9976d
commit e31b74073b
2 changed files with 55 additions and 9 deletions

View file

@ -110,6 +110,37 @@ function openDmg() {
run('open', [dmgPath])
}
const CREDENTIAL_ENV_SUFFIXES = [
'_API_KEY',
'_TOKEN',
'_SECRET',
'_PASSWORD',
'_CREDENTIALS',
'_ACCESS_KEY',
'_PRIVATE_KEY',
'_OAUTH_TOKEN'
]
const CREDENTIAL_ENV_NAMES = new Set([
'ANTHROPIC_BASE_URL',
'ANTHROPIC_TOKEN',
'AWS_ACCESS_KEY_ID',
'AWS_SECRET_ACCESS_KEY',
'AWS_SESSION_TOKEN',
'CUSTOM_API_KEY',
'GEMINI_BASE_URL',
'OPENAI_BASE_URL',
'OPENROUTER_BASE_URL',
'OLLAMA_BASE_URL',
'GROQ_BASE_URL',
'XAI_BASE_URL'
])
function isCredentialEnvVar(name) {
if (CREDENTIAL_ENV_NAMES.has(name)) return true
return CREDENTIAL_ENV_SUFFIXES.some(suffix => name.endsWith(suffix))
}
function launchFresh() {
if (!exists(APP_BIN)) {
die(`Missing app executable: ${APP_BIN}`)
@ -129,14 +160,21 @@ function launchFresh() {
fs.mkdirSync(hermesHome, { recursive: true })
fs.mkdirSync(cwd, { recursive: true })
const env = {
...process.env,
HERMES_DESKTOP_CWD: cwd,
HERMES_DESKTOP_IGNORE_EXISTING: '1',
HERMES_DESKTOP_TEST_MODE: 'fresh-install',
HERMES_DESKTOP_USER_DATA_DIR: userDataDir,
HERMES_HOME: hermesHome
// Strip every credential-shaped env var so the sandbox is actually fresh.
// Without this, shell-set OPENAI_API_KEY/OPENAI_BASE_URL/etc. leak into the
// packaged backend, making setup.status report "configured" while the
// agent's own credential resolution still fails.
const env = {}
for (const [key, value] of Object.entries(process.env)) {
if (isCredentialEnvVar(key)) continue
env[key] = value
}
env.HERMES_DESKTOP_CWD = cwd
env.HERMES_DESKTOP_IGNORE_EXISTING = '1'
env.HERMES_DESKTOP_TEST_MODE = 'fresh-install'
env.HERMES_DESKTOP_USER_DATA_DIR = userDataDir
env.HERMES_HOME = hermesHome
delete env.HERMES_DESKTOP_HERMES
delete env.HERMES_DESKTOP_HERMES_ROOT

View file

@ -35,6 +35,9 @@ import type { RpcEvent } from '@/types/hermes'
import type { ClientSessionState } from '../../types'
const PROVIDER_SETUP_ERROR_RE =
/No inference provider configured|no_provider_configured|OPENROUTER_API_KEY|OPENAI_API_KEY|ANTHROPIC_API_KEY|set an API key/i
interface MessageStreamOptions {
activeSessionIdRef: MutableRefObject<string | null>
hydrateFromStoredSession: (
@ -585,11 +588,16 @@ export function useMessageStream({
})
}
} else if (event.type === 'error') {
if (isActiveEvent) {
const errorMessage = payload?.message || 'Hermes reported an error'
const looksLikeProviderSetup = PROVIDER_SETUP_ERROR_RE.test(errorMessage)
if (looksLikeProviderSetup) {
requestDesktopOnboarding(errorMessage)
} else if (isActiveEvent) {
notify({
kind: 'error',
title: 'Hermes error',
message: payload?.message || 'Hermes reported an error'
message: errorMessage
})
}