eyaltoledano/claude-task-master · error · Error

getClient must be implemented by provider

Error message

getClient must be implemented by provider

What it means

This is an abstract-method guard: BaseAIProvider.getClient is abstract and must be overridden by each concrete provider subclass to return an SDK client instance. Throwing this error means a subclass (or a hand-rolled provider) failed to implement getClient, or getClient was invoked directly on the base class.

Source

Thrown at src/ai-providers/base-provider.js:267

	/**
	 * Common error handler
	 */
	handleError(operation, error) {
		const errorMessage = error.message || 'Unknown error occurred';
		log('error', `${this.name} ${operation} failed: ${errorMessage}`, {
			error
		});
		throw new Error(
			`${this.name} API error during ${operation}: ${errorMessage}`
		);
	}

	/**
	 * Creates and returns a client instance for the provider
	 * @abstract
	 */
	getClient(params) {
		throw new Error('getClient must be implemented by provider');
	}

	/**
	 * Returns if the API key is required
	 * @abstract
	 * @returns {boolean} if the API key is required, defaults to true
	 */
	isRequiredApiKey() {
		return true;
	}

	/**
	 * Returns the required API key environment variable name
	 * @abstract
	 * @returns {string|null} The environment variable name, or null if no API key is required
	 */
	getRequiredApiKeyName() {
		throw new Error('getRequiredApiKeyName must be implemented by provider');

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Implement getClient(params) in your provider subclass returning the provider's SDK client
  2. Check the method name spelling and that it's an own method (not lost via object spread)
  3. Extend an existing concrete provider (e.g. GoogleVertexProvider) instead of BaseAIProvider if you don't need custom client logic

Example fix

// before
class MyProvider extends BaseAIProvider {
  // no getClient
}
// after
class MyProvider extends BaseAIProvider {
  getClient(params) {
    return createMySdkClient({ apiKey: this.apiKey });
  }
}
Defensive patterns

Strategy: type-guard

Validate before calling

function checkProviderUsable(provider) {
  if (typeof provider.getClient !== 'function' || BaseAIProvider.prototype.getClient === provider.getClient) {
    throw new Error('Provider does not implement getClient');
  }
}

Type guard

function implementsGetClient(provider) {
  return typeof provider?.getClient === 'function' &&
    provider.getClient !== BaseAIProvider.prototype.getClient;
}

Try / catch

try {
  await provider.generateText({ messages, modelId });
} catch (e) {
  if (e.message === 'getClient must be implemented by provider') {
    throw new Error('Provider subclass is missing a getClient() override — fix the provider implementation');
  }
  throw e;
}

Prevention

When it happens

Trigger: Instantiating a custom provider that extends BaseAIProvider without overriding getClient, then calling generateText/streamText/etc., which internally calls this.client and therefore getClient. Also triggered by calling baseProvider.getClient(params) on the abstract base directly.

Common situations: Writing a new provider integration and forgetting the override; typos in the method name (e.g. getClient incorrectly cased); refactoring a provider that accidentally removed the method; mocking/partial-spreading a provider object that dropped the method.

Related errors


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/3d2924cebc88dd0e. Report an issue: GitHub.