Eugeny/tabby · error · Error
Not found
Error message
Not found
What it means
Thrown by VaultFileProvider.retrieveFile when the requested key has the correct `vault:` prefix and the id parses, but `vault.getSecret(VAULT_SECRET_TYPE_FILE, { id })` returns null - i.e. no stored file secret matches that id. The file was never stored, was deleted, or belongs to a different vault.
Source
Thrown at tabby-core/src/services/vault.service.ts:330
const id = (await wrapPromise(this.zone, promisify(crypto.randomBytes)(32))).toString('hex')
await this.vault.addSecret({
type: VAULT_SECRET_TYPE_FILE,
key: {
id,
description: `${description} (${transfer.getName()})`,
},
value: Buffer.from(await transfer.readAll()).toString('base64'),
})
return `${this.prefix}${id}`
}
async retrieveFile (key: string): Promise<Buffer> {
if (!key.startsWith(this.prefix)) {
throw new Error('Incorrect type')
}
const secret = await this.vault.getSecret(VAULT_SECRET_TYPE_FILE, { id: key.substring(this.prefix.length) })
if (!secret) {
throw new Error('Not found')
}
return Buffer.from(secret.value, 'base64')
}
}
View on GitHub (pinned to 14e2d60b9b)
Solutions
- Re-import the file into the vault via `selectAndStoreFile` to get a fresh key and update the referencing profile.
- Confirm the vault currently in use matches the one that originally stored the file (same passphrase/store); if the vault was reset, old ids are invalid.
- List current file secrets (`vault.secrets.filter(s => s.type === 'file')`) and verify the id before attempting retrieval.
- Catch the error in the caller and prompt the user to re-select the file rather than crashing the operation.
Example fix
// before
const secret = await this.vault.getSecret(VAULT_SECRET_TYPE_FILE, { id: key.substring(this.prefix.length) })
if (!secret) throw new Error('Not found')
// after - diagnose missing vs mismatched id
const id = key.substring(this.prefix.length)
const secret = await this.vault.getSecret(VAULT_SECRET_TYPE_FILE, { id })
if (!secret) {
const all = (await this.vault.load())?.secrets.filter(s => s.type === VAULT_SECRET_TYPE_FILE) ?? []
throw new Error(`Not found: file id ${id}. Known ids: ${all.map(s => (s.key as any).id).join(', ') || '(none)'}`)
} Defensive patterns
Strategy: validation
Validate before calling
async function vaultHasFile (vault: VaultService, id: string): Promise<boolean> {
const v = await vault.load()
if (!v) return false
return v.secrets.some(s => s.type === 'file' && (s.key as any).id === id)
}
const id = key.substring('vault:'.length)
if (!await vaultHasFile(vault, id)) {
throw new Error(`Vault has no file with id ${id}; re-import the file`)
} Type guard
function isVaultFileSecret (s: VaultSecret): s is VaultFileSecret {
return s.type === 'file' && typeof (s.key as any)?.id === 'string'
} Try / catch
try {
return await provider.retrieveFile(key)
} catch (e) {
if (e instanceof Error && e.message === 'Not found') {
// prompt re-import and update the referencing profile
return null
}
throw e
} Prevention
- Store a human-readable description with each file secret so missing ones are easy to identify.
- Validate stored file ids against the vault when a profile is loaded.
- Re-import files after a vault reset and update profile references.
- Avoid sharing vault file ids across machines via config-sync (they are vault-local).
When it happens
Trigger: Calling `retrieveFile('vault:<id>')` where `<id>` does not match any VaultFileSecret in the current vault's secrets list. Reachable after the secret was removed via updateSecret/deleteSecret, after re-creating the vault with a fresh passphrase, or when a key from another machine's vault is used.
Common situations: A profile references a private key stored in the vault that the user later deleted; vault was reset (new passphrase) wiping old secrets; config-sync imported a key id that exists only in the source machine's vault.
Related errors
AI-assisted analysis of Eugeny/tabby@14e2d60b9b (2026-08-12).
Data as JSON: /api/errors/3a848f8169a8ba81.
Report an issue: GitHub.