Skip to content

React Suspense cache (client._react) persists error results which prevents error recovery #3826

@hushin

Description

@hushin

Describe the bug

In urql's React Suspense mode, error results are cached in the internal React-specific cache (client._react) and persist even when:

  1. Error boundaries are reset
  2. The component is re-rendered

This behavior prevents proper error recovery in Suspense mode because cached errors are thrown repeatedly without attempting to refetch data.

Steps to reproduce:

  1. Start the app (invalid URL is set by default)
  2. Verify that the error is caught by the Error Boundary
  3. Click the "Try again" button to reset the Error Boundary
  4. Expected: A new request to /graphql appears in the Network tab
  5. Actual: No request is made - the cached error is thrown immediately

Root Cause Analysis

The issue is in packages/react-urql/src/hooks/useQuery.ts:

  1. Line 240-241: All OperationResults (including errors) are cached without filtering:
onPush(result => {
  cache.set(request.key, result); // Caches both success and error results
});
  1. Line 262-292: The cache is checked without considering error state:
let result = cache.get(request.key);
// Cached error results are returned without refetching
  1. cache.ts: The cache implementation treats errors as valid cache entries:
type CacheEntry = OperationResult | Promise<unknown> | undefined;
// OperationResult includes both success and error states

Expected Behavior

To allow for proper error recovery and retry mechanisms, I think it might be better if error results weren't cached in the Suspense cache. What do you think?

Proposed Solutions

Don't cache error results

onPush(result => {
  if (!result.error) {
    cache.set(request.key, result);
  }
});

Reproduction

https://github.com/hushin-sandbox/urql-react-suspense-error-cache-repro https://stackblitz.com/~/github.com/hushin-sandbox/urql-react-suspense-error-cache-repro

Urql version

  • urql: v5.0.1
  • @urql/core: v6.0.1

Validations

  • I can confirm that this is a bug report, and not a feature request, RFC, question, or discussion, for which GitHub Discussions should be used
  • Read the docs.
  • Follow our Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions