Eugeny/tabby · error · Error

Not found

Error message

Not found

What it means

Thrown by `FileProvidersService.retrieveFile` after it has iterated every registered FileProvider and each one either threw or had no match for the given key. It is the catch-all 'no provider could resolve this key' failure. The message is intentionally generic because the specific failure is provider-internal and swallowed.

Source

Thrown at tabby-core/src/services/fileProviders.service.ts:29

        private translate: TranslateService,
        @Inject(FileProvider) private fileProviders: FileProvider[],
    ) { }

    async selectAndStoreFile (description: string): Promise<string> {
        return this.selectProvider().then(p => {
            return p.selectAndStoreFile(description)
        })
    }

    async retrieveFile (key: string): Promise<Buffer> {
        for (const p of this.fileProviders) {
            try {
                return await p.retrieveFile(key)
            } catch {
                continue
            }
        }
        throw new Error('Not found')
    }

    async selectProvider (): Promise<FileProvider> {
        const providers: FileProvider[] = []
        await Promise.all(this.fileProviders.map(async p => {
            if (await p.isAvailable()) {
                providers.push(p)
            }
        }))
        if (!providers.length) {
            this.notifications.error(this.translate.instant('Vault master passphrase needs to be set to allow storing secrets'))
            throw new Error('No available file providers')
        }
        if (providers.length === 1) {
            return providers[0]
        }
        return this.selector.show(
            this.translate.instant('Select file storage'),

View on GitHub (pinned to 14e2d60b9b)

Solutions

  1. Check the key format: vault keys are prefixed (e.g. `vault:`), electron keys are `file://...` - confirm the key matches an existing entry.
  2. Ensure the vault is unlocked before retrieval (call `vault.load()` / unlock modal) so VaultFileProvider can return the secret.
  3. If the underlying file was deleted, re-import it via `selectAndStoreFile` to obtain a fresh key and update the referencing profile/config.
  4. Log per-provider errors (replace `catch { continue }` with `catch(e) { lastError = e; continue }`) to surface the real cause instead of the generic 'Not found'.

Example fix

// before
async retrieveFile (key: string): Promise<Buffer> {
    for (const p of this.fileProviders) {
        try { return await p.retrieveFile(key) }
        catch { continue }
    }
    throw new Error('Not found')
}

// after - capture the last error for diagnostics
async retrieveFile (key: string): Promise<Buffer> {
    let lastErr: unknown
    for (const p of this.fileProviders) {
        try { return await p.retrieveFile(key) }
        catch (e) { lastErr = e; continue }
    }
    throw new Error(`Not found: ${key} (last provider error: ${lastErr})`)
}
Defensive patterns

Strategy: try-catch

Validate before calling

async function fileExistsSomewhere (providers: FileProvider[], key: string): Promise<boolean> {
    for (const p of providers) {
        try { await p.retrieveFile(key); return true } catch { /* try next */ }
    }
    return false
}

// before retrieving
if (!await fileExistsSomewhere(fileProviders, key)) {
    throw new Error(`No provider has key ${key}; re-import the file`)
}

Type guard

function isVaultFileKey (key: string): boolean { return key.startsWith('vault:') }
function isElectronFileKey (key: string): boolean { return key.startsWith('file://') }

Try / catch

try {
    return await fileProviders.retrieveFile(key)
} catch (e) {
    if (e instanceof Error && e.message === 'Not found') {
        // prompt user to re-import; do not crash the consuming flow
        return await fileProviders.selectAndStoreFile('Re-import missing file')
    }
    throw e
}

Prevention

When it happens

Trigger: Calling `retrieveFile(key)` where `key` is unknown to all providers, has been deleted from the vault, references a file:// path that no longer exists on disk, or whose provider (vault/electron) is locked/unavailable so each provider rejects.

Common situations: A profile references a private-key file that was removed from the vault or whose source file was deleted; a config synced from another machine whose stored file key is local to that machine; vault locked so VaultFileProvider throws 'Vault is locked' and ElectronFileProvider throws 'Incorrect type'.

Related errors


AI-assisted analysis of Eugeny/tabby@14e2d60b9b (2026-08-12). Data as JSON: /api/errors/667066e24265ec25. Report an issue: GitHub.