# How Mermaid Handles Parsing Errors: ParseErrorFunction and DetailedError Types Explained

> Discover how Mermaid handles parsing errors with ParseErrorFunction and DetailedError types. Intercept syntax errors and get structured error objects for custom handling during diagram rendering.

- Repository: [mermaid-js/mermaid](https://github.com/mermaid-js/mermaid)
- Tags: internals
- Published: 2026-02-23

---

**Mermaid provides a `ParseErrorFunction` hook and `DetailedError` interface that allow developers to intercept syntax errors during diagram rendering, receiving structured error objects containing line numbers, column positions, and original error contexts.**

When rendering diagrams with the **mermaid-js/mermaid** library, syntax errors in diagram definitions can disrupt the rendering pipeline or produce opaque failure messages. The library exposes a flexible error handling mechanism through the `ParseErrorFunction` type and `DetailedError` interface, enabling applications to capture parsing diagnostics and provide user-friendly feedback. This system normalizes errors from the underlying Langium parser into a consistent format that custom handlers can process according to application needs.

## How Mermaid Processes Parsing Errors Internally

Mermaid separates syntax parsing from runtime rendering through a six-stage pipeline that transforms low-level parser exceptions into structured error objects.

**Stage 1: Parser Exception Generation**

Each diagram type is parsed by a Langium-based parser. When lexical or grammatical errors are detected, the parser throws a `MermaidParseError` (which extends the native JavaScript `Error` class) with a concatenated message containing line- and column-specific details. This occurs in [`packages/parser/src/parse.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/parser/src/parse.ts) at lines 73-97.

**Stage 2: API-Level Error Capture**

The `mermaidAPI.parse` method propagates the thrown error back to the higher-level wrapper (`mermaid.parse`). The `performCall` helper in [`packages/mermaid/src/mermaid.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaid.ts) (lines 62-66) manages this propagation, ensuring errors bubble up from the diagram-specific parser to the public API surface.

**Stage 3: Error Normalization via `handleError`**

The `handleError` helper receives the raw error (typed as `unknown`). If the object matches the `DetailedError` shape (containing `str`, `hash`, and other expected properties), it is pushed into an internal `errors` array. Otherwise, the error is wrapped into a `DetailedError`-like object containing a string message and optional name. This normalization occurs in [`packages/mermaid/src/mermaid.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaid.ts) at lines 64-78, ensuring the public `parseError` callback receives a consistent data structure regardless of the error source.

**Stage 4: `parseError` Hook Invocation**

The global `mermaid.parseError` callback (type `ParseErrorFunction`) is invoked with either `(msg, hash?)` when a `DetailedError` is available, or with a single string argument when only a plain message is present. This hook can be set directly via property assignment (`mermaid.parseError = fn`) or through the `setParseErrorHandler` helper method. The callback type is defined in [`packages/mermaid/src/Diagram.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/Diagram.ts) at lines 9-11, while invocation occurs in the same file as the normalization step.

**Stage 5: `DetailedError` Object Structure**

The `DetailedError` interface supplies a standardized error payload containing:
- `str` — the human-readable message
- `hash` — optional context metadata (e.g., line/column positions)
- `error?` — the original `Error` object for stack trace access
- `message?` — duplicate of `str` for convenience

This interface is defined in [`packages/mermaid/src/utils.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/utils.ts) at lines 83-90, and includes the `isDetailedError` runtime type guard to validate error shapes.

**Stage 6: Error Bubbling Behavior**

If `options.suppressErrors` is **false** (the default), the first `DetailedError` collected during a `run` call is re-thrown after all diagrams have been processed. This allows callers to catch parsing failures using standard `try/catch` blocks. The re-throwing logic resides in `runThrowsErrors` within [`packages/mermaid/src/mermaid.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaid.ts) at lines 96-100.

## ParseErrorFunction and DetailedError Type Definitions

Understanding the type signatures is essential for implementing custom error handlers that integrate cleanly with TypeScript codebases.

**ParseErrorFunction Interface**

Defined in [`packages/mermaid/src/Diagram.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/Diagram.ts), this type describes the callback signature:

```typescript
export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?: any) => void;

```

The `err` parameter accepts either a plain string, a full `DetailedError` object, or any unknown payload. The optional `hash` parameter provides secondary context historically used for line numbers and positional data.

**DetailedError Interface**

Defined in [`packages/mermaid/src/utils.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/utils.ts), this interface structures the normalized error:

```typescript
export interface DetailedError {
  str: string;          // readable error description
  hash: any;            // optional user-provided data (e.g., line/col)
  error?: any;          // original Error instance (if any)
  message?: string;     // duplicate of `str` for convenience
}

```

The companion type guard function validates runtime objects:

```typescript
export function isDetailedError(error: any): error is DetailedError {
  return 'str' in error;
}

```

This guard is exported from [`packages/mermaid/src/utils.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/utils.ts) and allows handlers to narrow union types safely.

## Implementing Custom Error Handlers in Mermaid

Developers can hook into the error pipeline at multiple integration points depending on their environment constraints.

### Registering a Global Error Handler

For environments where the global object might be frozen or when explicit API usage is preferred, use the `setParseErrorHandler` helper:

```javascript
// Register via the explicit helper
mermaid.setParseErrorHandler((msg, hash) => {
  console.warn('Mermaid parse error:', msg);
  if (hash) {
    console.warn('Additional context:', hash);
  }
});

```

*Source:* `setParseErrorHandler` implementation in [`packages/mermaid/src/mermaid.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaid.ts) (lines 90-106).

### Direct Assignment to parseError

In browser environments with standard global access, direct property assignment provides a simpler integration path:

```javascript
mermaid.parseError = (detail) => {
  if (typeof detail === 'string') {
    alert('Syntax error: ' + detail);
  } else {
    // `detail` is a DetailedError object
    alert(`Error: ${detail.str}\nAt: ${detail.hash}`);
  }
};

```

*Source:* Property defined on the `Mermaid` interface in [`packages/mermaid/src/mermaid.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaid.ts) (lines 34-36).

### Handling Errors with suppressErrors

When programmatically parsing diagram definitions, control error throwing behavior through the `suppressErrors` option:

```javascript
try {
  const result = await mermaid.parse('flowchart X\n a-->b', { suppressErrors: false });
  console.log('Parsed OK:', result);
} catch (e) {
  // e is a DetailedError (or array of them) if a custom handler is not set
  console.error('Parse failed:', e);
}

```

*Source:* `parse` wrapper implementation in [`packages/mermaid/src/mermaid.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaid.ts) (lines 47-66).

### Inspecting DetailedError Properties

Handlers should validate the error structure before accessing specific properties:

```javascript
mermaid.setParseErrorHandler((err) => {
  if (typeof err === 'object' && err.str) {
    console.log('Message:', err.str);
    console.log('Original error:', err.error);
    console.log('Context data:', err.hash);
  } else {
    console.log('String error:', err);
  }
});

```

*Source:* `DetailedError` interface definition in [`packages/mermaid/src/utils.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/utils.ts) (lines 83-90).

## Key Source Files for Error Handling

The error handling pipeline spans several modules across the mermaid monorepo:

- **[`packages/mermaid/src/mermaid.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaid.ts)** — Central orchestration including error capture via `handleError`, public `parse`/`render` wrappers, `setParseErrorHandler`, and the global `parseError` property assignment.

- **[`packages/mermaid/src/Diagram.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/Diagram.ts)** — Declares the `ParseErrorFunction` type that consumers implement to receive error notifications.

- **[`packages/mermaid/src/utils.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/utils.ts)** — Defines the `DetailedError` interface, the runtime type guard `isDetailedError`, and the `getErrorMessage` helper utility.

- **[`packages/parser/src/parse.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/parser/src/parse.ts)** — Implements the low-level Langium parser that throws `MermaidParseError` instances with rich line/column diagnostics.

## Summary

- **Mermaid normalizes all parsing errors** into `DetailedError` objects containing `str` (message), `hash` (context), and `error` (original exception) properties.
- **The `ParseErrorFunction` type** defines the callback signature for custom error handlers, accepting either strings or `DetailedError` objects.
- **Register handlers** via `mermaid.setParseErrorHandler()` for robust environments or direct `mermaid.parseError` assignment for simple browser integration.
- **Control error throwing** with the `suppressErrors` option in `mermaid.parse()` to handle errors programmatically rather than via global callbacks.
- **Source files** in [`packages/mermaid/src/mermaid.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/mermaid.ts) and [`packages/mermaid/src/utils.ts`](https://github.com/mermaid-js/mermaid/blob/main/packages/mermaid/src/utils.ts) contain the core error transformation logic and type definitions.

## Frequently Asked Questions

### What is the difference between ParseErrorFunction and DetailedError?

`ParseErrorFunction` is a **type alias** describing the callback signature `(err, hash?) => void` that developers implement to receive error notifications. `DetailedError` is an **interface** defining the structured error object shape containing `str`, `hash`, `error`, and `message` properties. The function receives the error data; the interface describes the data format.

### How do I access line and column numbers from a parsing error?

Access positional data through the `hash` property of the `DetailedError` object. When the Langium parser throws a `MermaidParseError`, the normalization process in `handleError` preserves line and column information within the `hash` field. Inspect `err.hash` inside your `ParseErrorFunction` implementation to extract specific location data.

### Can I suppress errors globally while still logging them?

Yes. Set `suppressErrors: true` in the parse options to prevent errors from throwing, while simultaneously registering a `parseError` handler to log or process errors. Alternatively, set a global handler and catch the re-thrown error at the application level using `try/catch` blocks around `mermaid.run()` or `mermaid.parse()` calls.

### What happens if I don't set a custom parseError handler?

Without a custom handler, errors follow the default pipeline: they are normalized to `DetailedError` objects, collected in an internal array, and if `suppressErrors` is false, the first error is re-thrown after processing completes. This results in standard JavaScript exceptions that can be caught with `try/catch`, though without custom UI feedback or logging during the rendering process.