usememos/memos · error
AI provider capability unsupported
Error message
AI provider capability unsupported
What it means
Sentinel error ai.ErrCapabilityUnsupported indicating the requested AI provider exists but does not support the capability being requested (as opposed to ErrProviderNotFound for a bad ID, or the STT/audio-LLM-specific sentinels). Compare with errors.Is rather than string matching.
Source
Thrown at internal/ai/errors.go:9
package ai
import "github.com/pkg/errors"
var (
// ErrProviderNotFound indicates that a requested provider ID does not exist.
ErrProviderNotFound = errors.New("AI provider not found")
// ErrCapabilityUnsupported indicates that the provider does not support the requested capability.
ErrCapabilityUnsupported = errors.New("AI provider capability unsupported")
// ErrSTTNotSupported indicates that the provider does not have a dedicated
// speech-to-text endpoint. Use the audiollm package for multimodal audio
// understanding when this is returned.
ErrSTTNotSupported = errors.New("provider does not support speech-to-text capability")
// ErrAudioLLMNotSupported indicates that the provider does not have a
// multimodal-audio LLM available in this codebase.
ErrAudioLLMNotSupported = errors.New("provider does not support multimodal audio capability")
)
View on GitHub (pinned to 14d757ce1f)
Solutions
- Switch the AI settings to a provider that supports the capability you are invoking (for speech-to-text see the dedicated STT providers; for multimodal audio see the audiollm path).
- Check errors.Is(err, ai.ErrCapabilityUnsupported) and route the user to a supported provider or a graceful 'unsupported' UI state.
- Review the provider capability matrix in the ai package/internal config and align the requested capability with a listed provider.
Example fix
// before
res, err := svc.Transcribe(ctx, req) // opaque error
// after
res, err := svc.Transcribe(ctx, req)
if err != nil {
if errors.Is(err, ai.ErrCapabilityUnsupported) {
return status.Errorf(codes.InvalidArgument, "configured AI provider lacks this capability; pick another provider")
}
return err
} Defensive patterns
Strategy: type-guard
Validate before calling
// Go — check capability support before requesting it
caps, ok := ai.ProviderCapabilities(providerID)
if !ok {
return ai.ErrProviderNotFound
}
if !caps.Has(ai.CapSTT) {
return status.Errorf(codes.InvalidArgument, "provider %q cannot transcribe; select an STT-capable provider", providerID)
} Type guard
// Go
func isCapabilityUnsupported(err error) bool {
return errors.Is(err, ai.ErrCapabilityUnsupported)
} Try / catch
res, err := svc.Invoke(ctx, req)
if err != nil {
switch {
case errors.Is(err, ai.ErrCapabilityUnsupported):
return status.Errorf(codes.InvalidArgument, "AI provider lacks this capability")
case errors.Is(err, ai.ErrProviderNotFound):
return status.Errorf(codes.NotFound, "AI provider not found")
}
return err
} Prevention
- Compare with errors.Is against the package sentinels; never string-match.
- Surface provider capability lists in the settings UI so users pick valid providers.
- On provider upgrades, re-run capability-related tests for every configured provider.
When it happens
Trigger: Calling the ai package's capability factory with a provider ID that exists but lacks the requested capability — e.g., asking a text-only provider for STT or multimodal audio, or a provider family whose driver implements one capability only. The dispatch layer returns this sentinel before constructing a client.
Common situations: Mixing provider types in AI settings (pointing STT at a chat-only provider); upgrading/downgrading where a capability was added or removed per provider; custom OpenAI-compatible endpoints that only proxy chat completions.
Related errors
- OpenAI API key is required
- SMTP host is required
- SMTP port must be between 1 and 65535
- from email is required
- SMTP server does not support STARTTLS
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/b6ee9a71fa2946fa.
Report an issue: GitHub.