Eugeny/tabby · error · Error
${profile.options.host}: jump host "${profile.options.jumpHo
Error message
${profile.options.host}: jump host "${profile.options.jumpHost}" not found in your config What it means
Thrown during SSH session setup when `profile.options.jumpHost` references a profile id that is not present in the loaded profiles list. The jump host is resolved by id (`profiles.find(x => x.id === jumpHost)`); a missing id means the proxy chain cannot be constructed, so connection is aborted before any socket is opened.
Source
Thrown at tabby-ssh/src/components/sshTab.component.ts:85
case 'open-sftp':
this.openSFTP()
break
}
})
super.ngOnInit()
}
async setupOneSession (injector: Injector, profile: SSHProfile, multiplex = true): Promise<SSHSession> {
let session = await this.sshMultiplexer.getSession(profile)
if (!multiplex || !session || !profile.options.reuseSession) {
session = new SSHSession(injector, profile)
if (profile.options.jumpHost) {
const jumpConnection = (await this.profilesService.getProfiles()).find(x => x.id === profile.options.jumpHost)
if (!jumpConnection) {
throw new Error(`${profile.options.host}: jump host "${profile.options.jumpHost}" not found in your config`)
}
const jumpSession = await this.setupOneSession(
this.injector,
this.profilesService.getConfigProxyForProfile<SSHProfile>(jumpConnection),
)
jumpSession.ref()
session.willDestroy$.subscribe(() => jumpSession.unref())
jumpSession.willDestroy$.subscribe(() => {
if (session?.open) {
session.destroy()
}
})
if (!(jumpSession.ssh instanceof russh.AuthenticatedSSHClient)) {
throw new Error('Jump session is not authenticated yet somehow')
}View on GitHub (pinned to 14e2d60b9b)
Solutions
- Open the profile settings and re-pick the jump host from the dropdown so the correct id is stored, or clear the jumpHost field.
- If the jump host profile was deleted, recreate it and re-select it, or remove the jumpHost reference.
- Validate profile integrity at config load: scan for jumpHost ids that no longer resolve and warn the user.
- Check that config-sync delivered the complete set of profiles (the jump host must be synced alongside its dependents).
Example fix
// before
if (!jumpConnection) throw new Error(`${profile.options.host}: jump host "${profile.options.jumpHost}" not found in your config`)
// after - validate references at config load and surface a list of candidates
const all = await this.profilesService.getProfiles()
const jumpConnection = all.find(x => x.id === profile.options.jumpHost)
if (!jumpConnection) {
const suggestions = all.filter(x => (x.options as any)?.host === profile.options.host).map(x => x.id)
throw new Error(`Jump host id "${profile.options.jumpHost}" not found. Did you mean: ${suggestions.join(', ') || '(no candidates)'}`)
} Defensive patterns
Strategy: validation
Validate before calling
async function jumpHostExists (profilesService: ProfilesService, jumpId: string | undefined): Promise<boolean> {
if (!jumpId) return true
const all = await profilesService.getProfiles()
return all.some(p => p.id === jumpId)
}
if (!await jumpHostExists(this.profilesService, profile.options.jumpHost)) {
throw new Error(`Jump host ${profile.options.jumpHost} not found; pick a valid profile or clear it`)
} Type guard
function hasValidJumpHost (profile: SSHProfile, all: Profile[]): boolean {
return !profile.options.jumpHost || all.some(p => p.id === profile.options.jumpHost)
} Try / catch
try {
session = await this.setupOneSession(injector, profile)
} catch (e) {
if (e instanceof Error && /jump host .* not found/.test(e.message)) {
// prompt user to re-pick or clear jumpHost, then retry
return
}
throw e
} Prevention
- Validate jumpHost references at config load and warn about dangling ids.
- Re-create deleted jump-host profiles or clear the reference before connecting.
- Sync the full profile set so jump hosts travel with their dependents.
- Use the profile picker UI (not manual id entry) to set jumpHost to avoid typos.
When it happens
Trigger: An SSH profile has `options.jumpHost = '<id>'` but no profile with that id exists in config. Occurs after the jump-host profile was deleted/renamed, after a config-sync that omitted it, or when the id was typed manually and is wrong.
Common situations: User deleted or renamed the jump/bastion profile but left references to it; config imported from another machine without the jump host; typo in the id; profile id changed after a migration.
Related errors
- Did not find any bootstrap components. Are there any plugins
- Vault not configured
- Not found
- No available file providers
- Vault is locked
AI-assisted analysis of Eugeny/tabby@14e2d60b9b (2026-08-12).
Data as JSON: /api/errors/17155bc31a34c238.
Report an issue: GitHub.