Start: serverFnFetcher unconditionally console.logs every server-function error, including benign cancellation AbortErrors

Open Beginner friendly
#7,873 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
typescript
Domain
api

Research direction

Start in packages/start-client-core/src/client-rpc/serverFnFetcher.ts at getResponse and inspect the catch block that logs non-Response errors. Use the linked reproduction and cancellation steps to verify the behavior. Done means re-thrown server-function errors, including AbortErrors, no longer produce the stray console log.

Written by the indexing model from the issue text.

Description

Which project does this relate to?

Start

Describe the bug

serverFnFetcher's getResponse logs every non-Response error thrown by a server-function call via console.log, then re-throws it. In packages/start-client-core/src/client-rpc/serverFnFetcher.ts:

async function getResponse(fn) {
  let response
  try {
    response = await fn()
  } catch (error) {
    if (error instanceof Response) response = error
    else {
      console.log(error)   // ← logs every error, incl. benign cancellations
      throw error
    }
  }
  // ...
}

Two problems:

  1. It's unconditional — there is no process.env.NODE_ENV guard, so it also runs in production builds (bundlers don't strip console.log by default), spamming the browser console for real users.
  2. It logs benign cancellations. When a caller passes an AbortSignal to a server function and aborts it (e.g. a request cancelled on navigation/unmount), the RPC fetch rejects with DOMException: signal is aborted without reason (AbortError). getResponse console.logs it and re-throws. The
    re-thrown error is then handled by the caller (who deliberately aborted and no longer cares about the result), so the throw itself is fine — but the console.log leaves a stray, stack-trace-bearing console entry with no context.

Because it's console.log (not console.error) on a caught-and-rethrown error, it can't be intercepted from application code: it never reaches a framework error hook or error boundary, and it isn't an unhandled promise rejection, so a window unhandledrejection listener doesn't catch it either.
The only app-side workarounds are monkey-patching console or patching the package.

Complete minimal reproducer

https://codesandbox.io/p/devbox/condescending-diffie-z59y9f

Steps to Reproduce the Bug
  1. Start Dev Server
  2. Open preview browser.
  3. Click the button
  4. examine browser dev console logs
Expected behavior

Cancelling a server-function call should not log to the console. More generally, getResponse should not console.log errors it re-throws — the caller is responsible for handling and reporting them. At minimum the log should be removed; if diagnostic logging is intended, gate it behind
process.env.NODE_ENV !== 'production' and skip cancellation errors (AbortError / CancelledError).

Screenshots or Videos

No response

Platform
  • @tanstack/react-start 1.168.30 (@tanstack/start-client-core 1.170.13)
  • React 19, Vite 8
  • Browser: Chrome (reproduces in both dev and production builds)
Additional context

No response

Dominant language
TypeScript
Stars
15.1k
Forks
1.9k
Avg merge
1d 19h
Merged PRs (30d)
136

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from TanStack/router

All issues in TanStack/router

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.