> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tool Errors

> Tell a missing tool apart from a broken one with ToolNotRegisteredError and ToolConstructionError

Building a tool instance can fail two ways — the tool isn't registered, or it is but its factory threw. Two error classes keep them apart.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    A[createToolInstance id] --> B{Registered?}
    B -->|No| C[ToolNotRegisteredError]
    B -->|Yes| D{Factory built ok?}
    D -->|No| E[ToolConstructionError]
    D -->|Yes| F([Tool Instance])

    classDef start fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef question fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef error fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef ok fill:#10B981,stroke:#7C90A0,color:#fff

    class A start
    class B,D question
    class C,E error
    class F ok
```

## Quick Start

**1. Catch and Discriminate**

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import {
  createToolInstance,
  ToolNotRegisteredError,
  ToolConstructionError,
} from 'praisonai';

try {
  const tool = createToolInstance('web-search', { apiKey });
} catch (err) {
  if (err instanceof ToolNotRegisteredError) {
    // Missing id — register the factory or fix the name.
  }
  if (err instanceof ToolConstructionError) {
    // Factory threw — err.cause has the underlying error.
  }
}
```

***

## Why Two Classes

Before PR #4902, building a missing tool and building a broken tool both returned `null` — hiding real bugs. Now the two failures are distinct.

| Situation | Before | After |
| - | - | - |
| Unknown id | `null` | `ToolNotRegisteredError` |
| Factory throws while building | `null` | `ToolConstructionError` (with `cause`) |

`ToolsRegistry.create` throws these instead of a generic `Error`, so callers can react to each.

***

## Error Fields

| Class | Field | Type | Description |
| - | - | - | - |
| `ToolNotRegisteredError` | `toolId` | `string` | The id that was not found |
| `ToolConstructionError` | `toolId` | `string` | The id whose factory failed |
| `ToolConstructionError` | `cause` | `unknown` | The error the factory threw |

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { createToolInstance, ToolConstructionError } from 'praisonai';

try {
  createToolInstance('web-search', { apiKey });
} catch (err) {
  if (err instanceof ToolConstructionError) {
    console.error(`Tool ${err.toolId} failed to build:`, err.cause);
  }
}
```

***

## Return null Instead of Throwing

When a tool is optional, `tryCreateToolInstance` returns `null` for a missing id — but still throws `ToolConstructionError` if the registered factory fails, so a broken tool never looks like a missing one.

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { tryCreateToolInstance } from 'praisonai';

const tool = tryCreateToolInstance('web-search', { apiKey });
if (!tool) {
  // Not registered — skip it.
} else {
  await tool.execute({ query: 'praisonai' });
}
```

***

## Validation Errors

`ToolValidationError` is separate — it comes from validating a tool **object**, not building a factory instance.

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { validate_tool, ToolValidationError } from 'praisonai';

try {
  validate_tool(myTool);
} catch (err) {
  if (err instanceof ToolValidationError) {
    console.error('Malformed tool:', err.message);
  }
}
```

`validate_tool` delegates to the tool's own `validate()` when present, listing every problem it finds.

***

## Best Practices

> [accordion] Handle both classes at build sites
>
> Catch `ToolNotRegisteredError` and `ToolConstructionError` separately — one is a config/name fix, the other a bug in the factory.

> [accordion] Log err.cause on construction failure
>
> `ToolConstructionError.cause` carries the underlying error the factory threw — log it, don't swallow it.

> [accordion] Use tryCreateToolInstance for optional tools
>
> Prefer returning `null` over catching for tools that may legitimately be absent, while still letting build failures surface.

***

## Related

> [card] [Factory Registry](https://praison.ai/docs/js/tools/factory-registry.md)
>
> Register builders, construct instances

> [card] [Custom Tools](https://praison.ai/docs/js/customtools.md)
>
> Name-keyed registry & validation


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.