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

  1. Verify the exact providerId string against the ids passed to editor.registerToolProvider (or the toolProviders config) in the server instance handling the request.
  2. Ensure the provider registration code actually executes at server startup (check for early returns/failed config loads before registration).
  3. If the id comes from stored data (pins, saved UI state), clean up or migrate stale provider ids referencing removed providers.
  4. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/d64c477c3a93133c. Report an issue: GitHub.