{"record":{"id":"df1217d48d031eda","repo":"AvaloniaUI/Avalonia","slug":"unable-to-select-a-suitable-storage-provider","errorCode":null,"errorMessage":"Unable to select a suitable storage provider","messagePattern":"Unable to select a suitable storage provider","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Platform/Storage/FallbackStorageProvider.cs","lineNumber":53,"sourceCode":"            yield return p;\n        for (;_nextProviderFactory < _factories.Length;)\n        {\n            var p = await _factories[_nextProviderFactory]();\n            _nextProviderFactory++;\n            if (p != null)\n            {\n                _providers.Add(p);\n                yield return p;\n            }\n        }\n    }\n    \n    async Task<IStorageProvider> GetFor(Func<IStorageProvider, bool> filter)\n    {\n        await foreach (var p in GetProviders())\n            if (filter(p))\n                return p;\n        throw new IOException(\"Unable to select a suitable storage provider\");\n    }\n    \n\n    // Those should _really_ have been asynchronous,\n    // but this class is expected to fall back to the managed implementation anyway\n    public bool CanOpen => true;\n    public bool CanSave => true;\n    public bool CanPickFolder => true;\n    \n    public async Task<IReadOnlyList<IStorageFile>> OpenFilePickerAsync(FilePickerOpenOptions options)\n    {\n        return await (await GetFor(p => p.CanOpen)).OpenFilePickerAsync(options);\n    }\n\n    public async Task<OpenFilePickerResult> OpenFilePickerWithResultAsync(FilePickerOpenOptions options)\n    {\n        return await (await GetFor(p => p.CanOpen)).OpenFilePickerWithResultAsync(options);\n    }","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Platform/Storage/FallbackStorageProvider.cs#L35-L71","documentation":"FallbackStorageProvider.GetFor(filter) enumerates the available IStorageProvider instances via GetProviders() and returns the first that satisfies the filter (e.g. CanOpen, CanSave, CanPickFolder). If the enumeration yields no match it throws IOException 'Unable to select a suitable storage provider'. This is the fallback aggregator used when the platform lacks a native picker.","triggerScenarios":"Calling OpenFilePickerAsync/SaveFilePickerAsync/FindFilePickerAsync on the fallback provider when every registered/injected provider reports the relevant capability (CanOpen/CanSave/CanPickFolder) as false, or no providers are registered at all.","commonSituations":"Running in a headless/server environment with no windowing backend, forgetting to attach the platform storage provider on a custom host, an integration test driving the fallback provider with no providers added, or a platform backend that incorrectly reports all capabilities as false.","solutions":["Register at least one IStorageProvider that supports the needed capability with the fallback provider before invoking the picker.","Guard the call: read StorageProvider.CanOpen/CanSave/CanPickFolder and skip the picker when false, showing a 'not supported' message instead.","On desktop platforms, ensure the windowing subsystem (e.g. Win32/X11/macOS backend) is initialized so its native storage provider is attached.","In tests/headless scenarios, inject a mock IStorageProvider that reports the required capability as true."],"exampleFix":"// before: call picker directly in an unsupported environment\nvar files = await StorageProvider.OpenFilePickerAsync(opts); // throws\n\n// after: guard capability and/or register a provider\nif (!StorageProvider.CanOpen) return;\nvar files = await StorageProvider.OpenFilePickerAsync(opts);","handlingStrategy":"validation","validationCode":"if (!StorageProvider.CanOpen) { ShowNotSupported(); return; }\nvar files = await StorageProvider.OpenFilePickerAsync(opts);","typeGuard":"bool CanPick(IStorageProvider p, Func<IStorageProvider,bool> need) => need(p);","tryCatchPattern":"try { await StorageProvider.OpenFilePickerAsync(opts); }\ncatch (IOException) { /* no provider: degrade to manual path entry */ }","preventionTips":["Always read CanOpen/CanSave/CanPickFolder before launching a picker.","Ensure the windowing backend is initialized so its native storage provider attaches.","Inject a mock provider reporting the needed capability in headless/test hosts.","Provide a fallback UX (manual path TextBox) when no provider is available."],"tags":["avalonia","storage","file-picker","platform","io"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}