mantinedev/mantine · error · Error

Request failed with status ${res.status}

Error message

Request failed with status ${res.status}

What it means

useFetch from @mantine/hooks wraps fetch and throws an Error with the HTTP status code when the response is not ok (status outside 200-299). The thrown error is captured in the hook's error state, so it typically surfaces as error.message in your UI rather than an uncaught exception.

Source

Thrown at packages/@mantine/hooks/src/use-fetch/use-fetch.ts:36

): UseFetchReturnValue<T> {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<Error | null>(null);
  const controller = useRef<AbortController | null>(null);

  const refetch = useCallback(() => {
    if (controller.current) {
      controller.current.abort();
    }

    controller.current = new AbortController();

    setLoading(true);

    return fetch(url, { ...options, signal: controller.current.signal })
      .then((res) => {
        if (!res.ok) {
          throw new Error(`Request failed with status ${res.status}`);
        }
        return res.json();
      })
      .then((res) => {
        setData(res);
        setLoading(false);
        return res as T;
      })
      .catch((err) => {
        setLoading(false);

        if (err.name !== 'AbortError') {
          setError(err);
        }

        return err;
      });
  }, [url, JSON.stringify(options)]);

View on GitHub (pinned to 8a284e2c2c)

Solutions

  1. Check error.message in the hook result and surface it in the UI instead of crashing
  2. Fix the URL or request options causing the non-2xx response
  3. Handle auth expiry: refresh the token and refetch() on 401
  4. Use the returned refetch to retry after transient server errors

Example fix

// before
const { data, loading, error } = useFetch(url);
if (loading) return <Loader />;
return <div>{data.message}</div>;

// after
const { data, loading, error } = useFetch(url);
if (loading) return <Loader />;
if (error) return <div>Request failed: {error.message}</div>;
return <div>{data.message}</div>;
Defensive patterns

Strategy: fallback

Validate before calling

const { data, error, loading, refetch } = useFetch(url);
// no pre-call validation possible; guard the result
if (error) {
  // handle non-2xx gracefully
}

Try / catch

// useFetch already captures the error in state — render defensively:
if (error) return <ErrorMessage onRetry={refetch}>{error.message}</ErrorMessage>;

Prevention

When it happens

Trigger: GET request to an endpoint returning 404, 401, 500, etc.; wrong URL path; expired auth token; backend down while returning error statuses via a proxy.

Common situations: API base URL misconfigured between dev/prod; hitting a route that does not exist in the mock server; auth session expired making the endpoint return 401/403; rate limiting returning 429.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of mantinedev/mantine@8a284e2c2c (2026-08-28). Data as JSON: /api/errors/837a586d4e2baee5. Report an issue: GitHub.