mastra-ai/mastra · error · HTTPException
UnknownToolProviderError.message (e.g. unknown tool provider
Error message
UnknownToolProviderError.message (e.g. unknown tool provider: ${providerId}) What it means
HTTP 404 raised by resolveProvider when editor.getToolProviderOrThrow(providerId) throws an UnknownToolProviderError, meaning no tool provider is registered in the Mastra editor under the given providerId. The library re-throws it as an HTTPException so the server returns 404 with the original message (e.g. 'unknown tool provider: ${providerId}'). Other errors from resolution are passed through unchanged.
Source
Thrown at packages/server/src/server/handlers/tool-providers.ts:85
_toolProviderModule = await import('@mastra/core/tool-provider');
}
return _toolProviderModule;
}
function requireEditor(editor: IMastraEditor | undefined): IMastraEditor {
if (!editor) {
throw new HTTPException(500, { message: 'Editor is not configured' });
}
return editor;
}
async function resolveProvider(editor: IMastraEditor, providerId: string): Promise<ToolProvider> {
try {
return editor.getToolProviderOrThrow(providerId);
} catch (error) {
const { UnknownToolProviderError } = await loadToolProviderModule();
if (error instanceof UnknownToolProviderError) {
throw new HTTPException(404, { message: error.message });
}
throw error;
}
}
// Emit a single warn per process when the connection-owner fallback fires.
// Multi-tenant deployments that forget to wire `mapUserToResourceId` (or
// `MASTRA_USER_KEY`) silently funnel every `caller-supplied` pin into one
// shared OAuth account — surface that misconfiguration once.
let defaultBucketWarned = false;
function warnDefaultBucketFallback(logger: IMastraLogger | undefined): void {
if (defaultBucketWarned) return;
defaultBucketWarned = true;
logger?.warn(
'[tool-providers] caller-supplied scope falling back to shared "default" bucket — ' +
'wire mapUserToResourceId or set MASTRA_USER_KEY to avoid cross-tenant OAuth sharing',
);
}View on GitHub (pinned to 75dd419e61)
Solutions
- Verify the exact providerId string against the ids passed to editor.registerToolProvider (or the toolProviders config) in the server instance handling the request.
- Ensure the provider registration code actually executes at server startup (check for early returns/failed config loads before registration).
- If the id comes from stored data (pins, saved UI state), clean up or migrate stale provider ids referencing removed providers.
- Confirm the deployed environment is the one where the provider is registered.
Example fix
// before await fetch(`/api/tool-providers/com.githun/providers`); // after await fetch(`/api/tool-providers/com.github/providers`); // matches registered provider id
Defensive patterns
Strategy: validation
Validate before calling
const registeredIds = await api.listToolProviders();
if (!registeredIds.includes(providerId)) {
throw new Error(`Provider '${providerId}' not registered; available: ${registeredIds.join(', ')}`);
} Try / catch
try {
await api.getProvider(providerId);
} catch (e) {
if (e.status === 404 && /unknown tool provider/i.test(e.message)) {
// refresh provider registry / show 'provider not found' UI
} else throw e;
} Prevention
- Keep provider ids in a single shared constants module used by both registration and client calls.
- Log the registered provider ids at server startup for quick comparison.
- Migrate/clean stale provider references when renaming or removing providers.
When it happens
Trigger: Any /api/tool-providers/:providerId/* route (schema, authorize, auth-status, connection-status, connections, disconnect) with a providerId that is not registered via editor.registerToolProvider / the Mastra config's tool providers.
Common situations: Typo in the providerId in client code or playground; provider registered only in a different Mastra instance/environment (dev vs prod); registration code never ran because of a config load failure; plugin/package version change renamed or removed a built-in provider id.
Related errors
- Tool provider ${providerId} does not support getToolSchema
- AcpAgent does not support resuming suspended generate calls
- ACP prompt stopped before completing: ${response.stopReason}
- server.drainTimeout must be a finite number between 0 and 21
- agent controller "${controllerId}" not found
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/d64c477c3a93133c.
Report an issue: GitHub.