# In-Message Error

In-Message Error [#in-message-error]

The **InMessageError** is an accessible per-message error/retry block rendered inline on a failed assistant message — not a global toast. It auto-extracts a readable message from the error and classifies common local-inference failures (OOM, WebGPU lost, model load) into a short hint, with a retry action that re-invokes generation. Data source: `useChat` (error state).

Preview [#preview]

```tsx
'use client';

/**
 * @file in-message-error-demo.tsx
 * @description Docs preview for `InMessageError`. Shows an OOM-style local
 * inference failure inline on an assistant turn with a working retry control.
 */
import * as React from 'react';
import { InMessageError } from '@/components/in-message-error';

export default function InMessageErrorDemo() {
  const [retries, setRetries] = React.useState(0);
  return (
    <div className="flex w-full max-w-lg flex-col gap-2">
      <InMessageError
        error={new Error('WebGPU out of memory while allocating KV cache')}
        onRetry={() => setRetries((r) => r + 1)}
      />
      {retries > 0 && (
        <p className="text-xs text-muted-foreground">
          Retry invoked {retries} time(s).
        </p>
      )}
    </div>
  );
}
```

Installation [#installation]

```bash
npx shadcn@latest add @localmode/ui/conversation/in-message-error
```

Data source & dependencies [#data-source--dependencies]

**Data source:** renders the error + retry callback you pass — works with any backend. Recommended producer: `useChat().error` and `useChat().regenerate()` from `@localmode/react` (on-device, optional).

* `clsx` + `tailwind-merge` — via the shared `cn()` util (installed automatically as a registry dependency)

Files installed [#files-installed]

* `in-message-error.tsx` — `InMessageError` + `extractErrorMessage`
* `lib/utils.ts` — the `cn()` helper (if not already present)

Props [#props]

**InMessageError**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `error` | `unknown` | — | **Required.** The error to surface (string or Error). |
| `onRetry` | `function` | — | Retry handler — re-invokes the failed generation. |
| `retryLabel` | `string` | `"Retry"` | Retry button label. |

Examples [#examples]

Inline error on a failed turn [#inline-error-on-a-failed-turn]

```tsx
import { useChat } from '@localmode/react';
import { InMessageError } from '@/components/in-message-error';

const { status, error, regenerate } = useChat({ model });

{status === 'error' && error && (
  <InMessageError error={error} onRetry={() => regenerate()} />
)}
```

`useChat().regenerate()` re-runs the last turn in place — on failure it restores the previous reply, so retry is safe to wire directly.

Customization [#customization]

The `classify()` helper maps error text to friendly hints — extend it for your provider’s error strings. `extractErrorMessage` is exported for reuse elsewhere.

These primitives are presentational and hook-driven: they render props and emit callbacks, holding only local view state. The orchestration state (e.g. `useChat`) lives in your app. Every surface uses shadcn/ui CSS-variable utilities, so it inherits your theme — restyle the copied file freely.