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

# Error messages

> Patterns for error messages that leave the reader with something to do next.

An error message is a touchpoint at the worst moment. A good one turns a frustrating
experience into a recoverable one; a bad one converts a small failure into an abandoned
session.

## Structure

Answer three questions:

1. **What happened** — describe the problem plainly.
2. **Why** — give context, if context helps.
3. **What to do next** — a clear action.

```
Good: "Could not save your changes. The connection was lost. Check your internet
       and try again."

Bad:  "Error 500: Internal Server Error"
```

## Tone

* **Calm** — errors are normal; do not alarm.
* **Helpful** — focus on the fix, not the cause.
* **Honest** — if you do not know why, say so.
* **Brief** — two sentences where possible.

### Do not blame the reader

```
Good: "That password is too short. Use at least 8 characters."
Bad:  "You entered an invalid password."

Good: "We could not find that page."
Bad:  "You requested a page that does not exist."
```

### Do not use jargon

```
Good: "Something went wrong. Please try again."
Bad:  "Unhandled exception in middleware pipeline."

Good: "Could not connect to the server."
Bad:  "ECONNREFUSED: Connection refused at 127.0.0.1:3000"
```

## Patterns by type

### Validation

Show inline, beside the field that needs attention, using `FormMessage` for consistent
styling.

```
Email address   -> "Enter a valid email address"
Password        -> "Password must be at least 8 characters"
Phone number    -> "Enter a phone number with country code (for example +263 77 123 4567)"
```

### Network

```
"Could not connect. Check your internet connection and try again."
"The request timed out. This usually means a slow connection. Try again in a moment."
"You appear to be offline. Your changes will be saved when you reconnect."
```

### Permission

```
"You do not have access to this page. Contact your administrator."
"Your session has expired. Sign in again to continue."
```

### Not found

```
"We could not find that page. Check the URL or go back to the home page."
"No results found for 'search term'. Try a different search."
```

### Server

```
"Something went wrong on our end. We are looking into it. Try again in a few minutes."
"This feature is temporarily unavailable. Please try again later."
```

## Implementation

### Form validation

```tsx theme={null}
const schema = z.object({
  email: z.string().email("Enter a valid email address"),
  password: z.string().min(8, "Password must be at least 8 characters"),
})
```

Put the message in the schema, not in the component. One definition, one wording, everywhere
the field appears.

### Toasts

```tsx theme={null}
toast.error("Could not save changes", {
  description: "Check your connection and try again.",
})
```

### Error boundaries

For a component-level crash, the boundary renders the recovery UI:

```tsx theme={null}
<SectionErrorBoundary section="Activity feed">
  <ActivityFeed />
</SectionErrorBoundary>
```

The boundary also logs the failure through the observability library, so a user-facing message
and an operator-facing log come from one place. See
[error boundaries](/patterns/error-boundaries).

## Examples

### Good

| Situation             | Message                                                  |
| --------------------- | -------------------------------------------------------- |
| Wrong password        | "Incorrect password. Try again or reset your password."  |
| File too large        | "This file is too large. Maximum size is 10 MB."         |
| Rate limited          | "Too many attempts. Wait a moment and try again."        |
| Offline               | "You are offline. Changes will sync when you reconnect." |
| Unavailable in region | "This feature is not yet available in your region."      |

### Bad

| Message                       | Problem                                  |
| ----------------------------- | ---------------------------------------- |
| "Error"                       | No context, no action                    |
| "Invalid input"               | Which input? What is wrong with it?      |
| "Something went wrong", alone | No next step                             |
| "Null pointer exception"      | Jargon                                   |
| "Please contact support"      | Lazy — offer a self-service option first |
