NousResearch/hermes-agent · error · Error
First-run remote setup completed without a saved remote back
Error message
First-run remote setup completed without a saved remote backend.
What it means
Thrown during first-run backend startup in the Hermes desktop app. When waitForDecision(backend) returns 'remote-applied', the code re-resolves the saved remote backend; if resolveRemote() returns nothing, the wizard claimed the remote was applied but nothing was persisted. This is an internal invariant failure, not a user-input error.
Source
Thrown at apps/desktop/electron/primary-backend-startup.ts:54
}: PrimaryBackendStartupOptions<Backend, RuntimeBackend, Remote, Connection>): Promise<
PrimaryBackendStartupResult<RuntimeBackend, Connection>
> {
const savedRemote = await resolveRemote()
if (savedRemote) {
return { kind: 'remote', connection: await connectRemote(savedRemote) }
}
await waitForLocalStart()
const backend = await prepareLocalBackend()
const decision = await waitForDecision(backend)
if (decision === 'remote-applied') {
const appliedRemote = await resolveRemote()
if (!appliedRemote) {
throw new Error('First-run remote setup completed without a saved remote backend.')
}
return { kind: 'remote', connection: await connectRemote(appliedRemote) }
}
if (decision === 'reset') {
throw new FirstRunSetupResetError()
}
return { kind: 'local', backend: await ensureLocalRuntime(backend) }
}
View on GitHub (pinned to c896c09c42)
Solutions
- Compare the wizard's apply-step write (file, key, schema) against exactly what resolveRemote() reads — a mismatch is the usual cause.
- Re-run first-run setup (reset the first-run marker) and walk the remote wizard again; if it persists this time, the first attempt hit a transient write failure.
- Check filesystem permissions and disk space where the remote config is stored so writes cannot fail silently.
- If reproducible, instrument the 'remote-applied' branch to log the result of the apply write immediately after it returns.
Example fix
// before
if (decision === 'remote-applied') {
const appliedRemote = await resolveRemote()
if (!appliedRemote) throw new Error('First-run remote setup completed without a saved remote backend.')
return { kind: 'remote', connection: await connectRemote(appliedRemote) }
}
// after (fall back to the already-prepared local backend instead of crashing first run)
if (decision === 'remote-applied') {
const appliedRemote = await resolveRemote()
if (!appliedRemote) {
log.error('remote-applied but resolveRemote() empty; remote config never persisted')
return { kind: 'local', backend: await ensureLocalRuntime(backend) }
}
return { kind: 'remote', connection: await connectRemote(appliedRemote) }
} Defensive patterns
Strategy: try-catch
Validate before calling
if (decision === 'remote-applied') {
const appliedRemote = await resolveRemote()
if (!appliedRemote) {
// fall back to the already-prepared local backend rather than crashing first run
return { kind: 'local', backend: await ensureLocalRuntime(backend) }
}
} Try / catch
try {
return await startPrimaryBackend()
} catch (e) {
if (e instanceof Error && e.message === 'First-run remote setup completed without a saved remote backend.') {
// the remote config never landed: re-run the first-run wizard
return await startFirstRunWizard()
}
if (e instanceof FirstRunSetupResetError) return null // user reset: expected path
throw e
} Prevention
- Verify config writes in the wizard's apply step with a read-back check.
- Keep the wizard's write key/schema and resolveRemote()'s read key/schema in one shared constant.
- Guard config writes against concurrent clears with a lock or single-writer rule.
When it happens
Trigger: decision === 'remote-applied' but a subsequent resolveRemote() yields null/undefined — the wizard's apply step failed to persist, wrote to a different location/key than resolveRemote() reads, or a concurrent reset/clear removed the config between apply and resolve.
Common situations: Config write race during first run (app quit or another window cleared config mid-wizard); a version mismatch where the wizard persists the remote under a key or schema the resolver does not read; permissions failure writing the config file so the apply write failed silently.
Related errors
- gh pr create failed (is gh installed and authenticated?)
- Branch name is required.
- Secure token storage is unavailable (no OS keyring service w
- Failed to encrypt the remote gateway token for secure storag
- An update is already in progress.
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/168a91cc4ac76a45.
Report an issue: GitHub.