# How to Handle Errors Using Composio's Error Types and Validation

> Master Composio error handling with ComposioError. Learn to use consistent code, possible fixes, and cause properties for predictable SDK error management. Explore Composio's structured system today.

- Repository: [Composio/composio](https://github.com/composiohq/composio)
- Tags: how-to-guide
- Published: 2026-02-19

---

**Composio provides a structured error-handling system built around the `ComposioError` base class, exposing consistent properties like `code`, `possibleFixes`, and `cause` to enable predictable error handling across all SDK operations.**

The Composio SDK implements a robust hierarchy of error types to standardize failure handling across tools, triggers, and validation workflows. When you handle errors using Composio's error types and validation system, you gain access to machine-readable error codes, human-readable suggestions, and preserved stack traces that simplify debugging in production environments.

## Understanding the Composio Error Hierarchy

### The ComposioError Base Class

All SDK errors extend `ComposioError`, defined in [`ts/packages/core/src/errors/ComposioError.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/errors/ComposioError.ts). This base class enforces a consistent interface across every error instance:

- `code`: Machine-readable identifier (e.g., `VALIDATION_ERROR`, `TOOL_EXECUTION_ERROR`)
- `message`: Human-readable description of what went wrong
- `possibleFixes`: Array of actionable suggestions to resolve the issue
- `cause`: The underlying error that triggered this failure (e.g., a Zod validation error)
- `stack`: Standard JavaScript stack trace

### Domain-Specific Error Types

The SDK organizes errors by domain under `ts/packages/core/src/errors/`:

- **ValidationErrors.ts**: Wraps Zod schema failures (`ValidationError`, `JsonSchemaToZodError`)
- **ToolErrors.ts**: Handles tool execution failures and provider-side errors
- **ToolkitErrors.ts**: Manages toolkit discovery and permission issues
- **TriggerErrors.ts**: Covers webhook and trigger configuration errors
- **SDKErrors.ts**: Generic SDK failures including authentication and configuration errors

All exports are centralized in [`ts/packages/core/src/errors/index.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/errors/index.ts) for clean imports.

## How Validation Errors Work

Composio uses Zod for runtime type validation. When you call a method with invalid arguments, the SDK catches the resulting `ZodError` and wraps it in a `ValidationError` instance.

The validation flow follows these steps:

1. The SDK method receives input arguments typed with Zod schemas
2. Zod validates the input against the schema definition
3. If validation fails, the SDK catches the `ZodError`
4. `ValidationError` extracts Zod issues and builds a user-friendly message with `possibleFixes` entries like `"[invalid_type] userId – Expected string, received number"`
5. The populated `ValidationError` is thrown to the caller with the original Zod error preserved in `cause`

This approach preserves type safety while providing actionable debugging information.

## Practical Examples to Handle Errors

### Basic Try-Catch Implementation

Use `instanceof` checks to handle specific error types while maintaining a fallback for generic failures:

```typescript
import { Composio } from '@composio/core';
import { ValidationError, ComposioError } from '@composio/core/errors';

const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });

async function run() {
  try {
    const result = await composio.tools.execute('GITHUB_CREATE_REPO', {
      userId: 'user_123',
      arguments: { repoName: 42 } // Intentional type error
    });
    console.log('Tool succeeded', result);
  } catch (err) {
    if (err instanceof ValidationError) {
      console.error('Validation failed:', err.message);
      console.error('Suggested fixes:', err.possibleFixes);
    } else if (err instanceof ComposioError) {
      console.error(`SDK Error (${err.code}): ${err.message}`);
    } else {
      console.error('Unexpected error:', err);
    }
  }
}

run();

```

### Express Middleware Integration

Centralize error handling in Express applications by checking for `ComposioError` instances in your error middleware:

```typescript
import express from 'express';
import { ComposioError, ValidationError } from '@composio/core/errors';

const app = express();
app.use(express.json());

app.post('/run-tool', async (req, res, next) => {
  try {
    const { toolSlug, arguments: args, userId } = req.body;
    const result = await composio.tools.execute(toolSlug, {
      userId,
      arguments: args,
    });
    res.json(result);
  } catch (err) {
    next(err);
  }
});

app.use((err: unknown, _req, res, _next) => {
  if (err instanceof ValidationError) {
    res.status(400).json({
      error: err.code,
      message: err.message,
      fixes: err.possibleFixes,
    });
    return;
  }

  if (err instanceof ComposioError) {
    res.status(500).json({ 
      error: err.code, 
      message: err.message 
    });
    return;
  }

  res.status(500).json({ 
    error: 'UNKNOWN', 
    message: String(err) 
  });
});

app.listen(3000);

```

### Inspecting Zod Validation Details

Access the underlying Zod error for advanced debugging or automated remediation:

```typescript
import { ValidationError } from '@composio/core/errors';
import type { ZodError } from 'zod';

try {
  await composio.tools.execute('SLACK_SEND_MESSAGE', {
    userId: 'user_abc',
    arguments: { channel: '', text: 123 }
  });
} catch (err) {
  if (err instanceof ValidationError && err.cause instanceof ZodError) {
    console.log('Raw Zod issues:', err.cause.issues);
    
    err.cause.issues.forEach(issue => {
      console.log(`Path: ${issue.path.join('.')} - ${issue.message}`);
    });
  }
}

```

## Summary

- **ComposioError** serves as the universal base class for all SDK errors, providing consistent `code`, `message`, `possibleFixes`, and `cause` properties.
- Domain-specific subclasses like **ValidationError**, **ToolErrors**, and **TriggerErrors** live in `ts/packages/core/src/errors/` and allow precise error handling.
- Validation failures wrap **Zod** errors automatically, preserving detailed schema violation information while presenting user-friendly fix suggestions.
- Use `instanceof` checks against `ComposioError` or its subclasses to implement type-safe error handling in both client scripts and server middleware.

## Frequently Asked Questions

### What is the difference between ComposioError and ValidationError?

**ComposioError** is the abstract base class that defines the common interface for all SDK errors, including properties like `code` and `possibleFixes`. **ValidationError** extends `ComposioError` specifically to wrap Zod schema validation failures, adding context about which input fields failed validation and why. When you catch a validation problem, it will be an instance of `ValidationError`, which is also an instance of `ComposioError`.

### How do I access the original Zod error for debugging?

The original Zod error is preserved in the `cause` property of any `ValidationError`. You can access it by checking `err.cause instanceof ZodError` after importing the `ZodError` type from the `zod` package. This gives you access to the raw `issues` array containing detailed path information and specific constraint violations.

### Can I use Composio error types in Express middleware?

Yes, Composio error types work seamlessly with Express error-handling middleware. Import `ComposioError` and its subclasses from `@composio/core/errors`, then use `instanceof` checks in your error middleware to return appropriate HTTP status codes and JSON responses. The `possibleFixes` array is particularly useful for returning actionable error details to API clients.

### Where are the error classes defined in the Composio repository?

All error classes are located in `ts/packages/core/src/errors/`. The base class `ComposioError` is defined in [`ComposioError.ts`](https://github.com/ComposioHQ/composio/blob/main/ComposioError.ts), while domain-specific errors reside in separate files like [`ValidationErrors.ts`](https://github.com/ComposioHQ/composio/blob/main/ValidationErrors.ts), [`ToolErrors.ts`](https://github.com/ComposioHQ/composio/blob/main/ToolErrors.ts), [`ToolkitErrors.ts`](https://github.com/ComposioHQ/composio/blob/main/ToolkitErrors.ts), [`TriggerErrors.ts`](https://github.com/ComposioHQ/composio/blob/main/TriggerErrors.ts), and [`SDKErrors.ts`](https://github.com/ComposioHQ/composio/blob/main/SDKErrors.ts). A barrel export in [`index.ts`](https://github.com/ComposioHQ/composio/blob/main/index.ts) simplifies importing these classes into your application.