---
title: "Errors Overview"
description: "FrontMCP provides a comprehensive error hierarchy with MCP-compliant error codes for proper JSON-RPC error responses."
icon: "triangle-exclamation"
keywords: ['frontmcp', 'mcp', 'model context protocol', 'sdk', 'reference', 'api', 'errors', 'exceptions', 'error handling', 'typescript']
---

## MCP Error Codes

```typescript
export const MCP_ERROR_CODES = {
  UNAUTHORIZED: -32001,          // Missing credentials
  RESOURCE_NOT_FOUND: -32002,    // Resource not found
  FORBIDDEN: -32003,             // Invalid/insufficient credentials
  INVALID_REQUEST: -32600,       // Invalid request
  METHOD_NOT_FOUND: -32601,      // Method not found
  INVALID_PARAMS: -32602,        // Invalid parameters
  INTERNAL_ERROR: -32603,        // Internal server error
  PARSE_ERROR: -32700,           // Parse error
} as const;
```

## Error Hierarchy

```
McpError (abstract)
├── PublicMcpError (safe to expose to clients)
│   ├── ToolNotFoundError
│   ├── ResourceNotFoundError
│   ├── InvalidInputError
│   ├── UnauthorizedError
│   ├── RateLimitError
│   └── ...
│
└── InternalMcpError (hide details from clients)
    ├── ToolExecutionError
    ├── ResourceReadError
    ├── InvalidOutputError
    └── ...
```

## Base Error Classes

### McpError (Abstract)

Base class for all MCP-related errors.

```typescript
abstract class McpError extends Error {
  readonly errorId: string;           // Unique ID for tracking
  abstract isPublic: boolean;         // Expose details to clients?
  abstract statusCode: number;        // HTTP status code
  abstract code: string;              // Error code

  abstract getPublicMessage(): string;
  getInternalMessage(): string;
  toMcpError(isDevelopment?: boolean): McpErrorResponse;
}
```

### PublicMcpError

Errors safe to expose to clients (validation errors, not found, etc.).

```typescript
class PublicMcpError extends McpError {
  readonly isPublic = true;
  /** Optional `WWW-Authenticate` response header value (e.g. `'Bearer'`) for 401 challenges. */
  readonly wwwAuthenticate?: string;

  constructor(message: string, code?: string, statusCode?: number, wwwAuthenticate?: string);
}
```

### InternalMcpError

Errors that should NOT expose details (server errors, unexpected failures).

```typescript
class InternalMcpError extends McpError {
  readonly isPublic = false;
  readonly statusCode = 500;

  getPublicMessage(): string {
    return `Internal FrontMCP error. Contact support with ID: ${this.errorId}`;
  }
}
```

## Error Categories

<CardGroup cols={2}>
  <Card title="Tool & Prompt Errors" icon="wrench" href="/frontmcp/sdk-reference/errors/tool-errors">
    ToolNotFoundError, ToolExecutionError, PromptNotFoundError, PromptExecutionError
  </Card>
  <Card title="Resource Errors" icon="file" href="/frontmcp/sdk-reference/errors/resource-errors">
    ResourceNotFoundError, ResourceReadError, InvalidResourceUriError
  </Card>
  <Card title="Validation Errors" icon="check" href="/frontmcp/sdk-reference/errors/validation-errors">
    InvalidInputError, InvalidOutputError, InvalidMethodError, MissingPromptArgumentError
  </Card>
  <Card title="Auth Errors" icon="lock" href="/frontmcp/sdk-reference/errors/auth-errors">
    UnauthorizedError, AuthConfigurationError, SessionMissingError, AuthorizationRequiredError
  </Card>
  <Card title="Agent Errors" icon="robot" href="/frontmcp/sdk-reference/errors/agent-errors">
    AgentNotFoundError, AgentExecutionError, AgentLoopExceededError, AgentTimeoutError
  </Card>
  <Card title="Rate Limit Errors" icon="gauge" href="/frontmcp/sdk-reference/errors/rate-limit-errors">
    RateLimitError, QuotaExceededError
  </Card>
  <Card title="Transport Errors" icon="plug" href="/frontmcp/sdk-reference/errors/transport-errors">
    TransportNotConnectedError, UnsupportedContentTypeError
  </Card>
  <Card title="Remote Errors" icon="tower-broadcast" href="/frontmcp/sdk-reference/errors/remote-errors">
    RemoteConnectionError, RemoteTimeoutError, RemoteToolNotFoundError
  </Card>
  <Card title="Elicitation Errors" icon="comment-dots" href="/frontmcp/sdk-reference/errors/elicitation-errors">
    ElicitationNotSupportedError, ElicitationTimeoutError, ElicitationFallbackRequired
  </Card>
  <Card title="Provider Errors" icon="cubes" href="/frontmcp/sdk-reference/errors/provider-errors">
    ProviderNotRegisteredError, DependencyCycleError, ProviderConstructionError
  </Card>
  <Card title="Registry Errors" icon="database" href="/frontmcp/sdk-reference/errors/registry-errors">
    RegistryDefinitionNotFoundError, FlowNotRegisteredError, EntryValidationError
  </Card>
  <Card title="Decorator Errors" icon="at" href="/frontmcp/sdk-reference/errors/decorator-errors">
    InvalidDecoratorMetadataError, HookTargetNotDefinedError
  </Card>
  <Card title="Normalization Errors" icon="filter" href="/frontmcp/sdk-reference/errors/normalization-errors">
    MissingProvideError, InvalidUseClassError, InvalidEntityError
  </Card>
  <Card title="SDK Errors" icon="gear" href="/frontmcp/sdk-reference/errors/sdk-errors">
    FlowExitedWithoutOutputError, ServerNotFoundError, ConfigNotFoundError
  </Card>
  <Card title="Auth Internal Errors" icon="shield-halved" href="/frontmcp/sdk-reference/errors/auth-internal-errors">
    EncryptionContextNotSetError, VaultLoadError, TokenLeakDetectedError
  </Card>
  <Card title="ESM Errors" icon="box-open" href="/frontmcp/sdk-reference/errors/esm-errors">
    EsmPackageLoadError, EsmVersionResolutionError, EsmManifestInvalidError, EsmCacheError, EsmRegistryAuthError, EsmInvalidSpecifierError
  </Card>
</CardGroup>

## Usage Patterns

### Throwing Errors

```typescript
import { ToolNotFoundError, InvalidInputError } from '@frontmcp/sdk';

@Tool({ name: 'my_tool', inputSchema: { id: z.string() } })
class MyTool extends ToolContext {
  async execute(input: { id: string }) {
    if (!input.id) {
      throw new InvalidInputError('ID is required');
    }

    const item = await this.get(Service).find(input.id);
    if (!item) {
      throw new ToolNotFoundError('my_tool');
    }

    return item;
  }
}
```

### Using fail()

```typescript
@Tool({ name: 'my_tool', inputSchema: {} })
class MyTool extends ToolContext {
  async execute(input) {
    if (!valid) {
      this.fail(new InvalidInputError('Validation failed'));
      // Never reaches here - fail() throws
    }
  }
}
```

### Error with Details

```typescript
throw new InvalidInputError('Validation failed', {
  field: 'email',
  reason: 'Invalid format',
});
```

### Custom toJsonRpcError

Some errors override `toJsonRpcError()` for custom data:

```typescript
class ResourceNotFoundError extends PublicMcpError {
  toJsonRpcError() {
    return {
      code: MCP_ERROR_CODES.RESOURCE_NOT_FOUND,
      message: this.getPublicMessage(),
      data: { uri: this.uri },
    };
  }
}
```

## Error Properties

| Property       | Type      | Description                             |
| -------------- | --------- | --------------------------------------- |
| `errorId`      | `string`  | Unique ID for tracking (auto-generated) |
| `isPublic`     | `boolean` | Whether to expose message to clients    |
| `statusCode`   | `number`  | HTTP status code equivalent             |
| `wwwAuthenticate` | `string?` | Optional `WWW-Authenticate` header value (e.g. `'Bearer'`) for 401 challenges |
| `code`         | `string`  | Error code for categorization           |
| `mcpErrorCode` | `number`  | JSON-RPC error code (optional)          |

## Best Practices

### Use Specific Error Classes

```typescript
// Good
throw new ToolNotFoundError('my_tool');
throw new InvalidInputError('Email is required');

// Avoid
throw new Error('Tool not found');
```

### Preserve Original Errors

```typescript
try {
  await externalService.call();
} catch (error) {
  throw new ToolExecutionError('my_tool', error);
}
```

### Don't Expose Internal Details

```typescript
// InternalMcpError hides message from clients
throw new InternalMcpError('Database connection failed: timeout after 30s');
// Client sees: "Internal FrontMCP error. Contact support with ID: err_abc123"
```

### Use Error IDs for Tracking

```typescript
try {
  // operation
} catch (error) {
  if (error instanceof McpError) {
    logger.error('Operation failed', {
      errorId: error.errorId,
      code: error.code,
    });
  }
  throw error;
}
```

## Import

```typescript
import {
  MCP_ERROR_CODES,
  McpError,
  PublicMcpError,
  InternalMcpError,
  ToolNotFoundError,
  ToolExecutionError,
  ResourceNotFoundError,
  ResourceReadError,
  InvalidInputError,
  InvalidOutputError,
  UnauthorizedError,
  RateLimitError,
  // ... more
} from '@frontmcp/sdk';
```
