10 / 37 · Messages
Error state
A quiet failure banner with a retry path, not a modal in your face.
Generation stopped
The model hit the output limit after 4,096 tokens.
Installation
npx shadcn@latest add "@assistant-ui/elements-error-state"
Usage
import { ErrorState } from "@/components/elements/error-state";
<ErrorState
title="Request failed"
detail="The model timed out."
retrying={false}
onRetry={() => {}}
/>Props
title*stringPrimary failure headline shown in the banner.
detail*stringSupporting detail under the title explaining what went wrong.
retrying*booleanWhen true the banner swaps to a spinning Retrying status instead of the error.
onRetry*() => voidCalled when the retry control is pressed.
classNamestringExtra classes merged onto the root.
Source
error-state.tsx"use client";
import { CircleAlertIcon, RefreshCwIcon } from "lucide-react";
import { cn } from "@/lib/utils";
export interface ErrorStateProps {
title: string;
detail: string;
retrying: boolean;
onRetry: () => void;
className?: string;
}
export function ErrorState({
title,
detail,
retrying,
onRetry,
className,
}: ErrorStateProps) {
if (retrying) {
return (
<div
key="retrying"
role="status"
className={cn(
"fade-in animate-in flex w-full max-w-sm items-center gap-2.5 text-sm duration-300 motion-reduce:animate-none",
className,
)}
>
<RefreshCwIcon className="text-foreground/45 size-3.5 shrink-0 animate-spin motion-reduce:animate-none" />
<span className="text-foreground/55 relative inline-block">
<span>Retrying</span>
<span
aria-hidden
className="shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
>
Retrying
</span>
</span>
</div>
);
}
return (
<div
key="error"
role="alert"
className={cn(
"fade-in animate-in flex w-full max-w-sm items-start gap-2.5 rounded-2xl bg-red-500/[0.06] px-4 py-3 text-sm duration-300 motion-reduce:animate-none dark:bg-red-500/10",
className,
)}
>
<CircleAlertIcon className="mt-0.5 size-4 shrink-0 text-red-500/80" />
<div>
<p className="font-medium text-red-600 dark:text-red-400">{title}</p>
<p className="mt-0.5 text-[13px] leading-snug text-red-600/60 dark:text-red-400/60">
{detail}
</p>
</div>
<button
type="button"
onClick={onRetry}
className="ms-auto flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium text-red-600 transition-colors hover:bg-red-500/10 dark:text-red-400"
>
<RefreshCwIcon className="size-3" />
Retry
</button>
</div>
);
}