nodejs / nodejs/undici

Uncaught AssertionError thrown due to a possible race condition?

Open
#4,059 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
JavaScript
Stars
7.7k
Forks
880
Avg merge
2d 16h
Merged PRs (30d)
68

Description

Bug Description

I run an application which makes a lot of requests per second using HTTP/2 over a fixed pool of about 500 Dispatchers.

Everything works great but sometimes when the upstream tends to have a higher error rate, these errors come in the form of a weird assertion error within our logs as uncaught promise rejections.

Reproducible By

I am not sure how I could provide a reproducible example for this as it does happen randomly and is certainly tied to upstream request failures.

Expected Behavior

The request failure should be properly thrown and caught by the request itself instead of the global unhandled rejection handler within our application.

Logs & Screenshots

AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
    
      assert(this.callback)
    
        at RequestHandler.onConnect (/root/cluster-worker/node_modules/undici/lib/api/api-request.js:82:5)
        at Request.onConnect (/root/cluster-worker/node_modules/undici/lib/core/request.js:228:29)
        at writeH2 (/root/cluster-worker/node_modules/undici/lib/dispatcher/client-h2.js:345:13)
        at Object.write (/root/cluster-worker/node_modules/undici/lib/dispatcher/client-h2.js:119:14)
        at _resume (/root/cluster-worker/node_modules/undici/lib/dispatcher/client.js:601:50)
        at resume (/root/cluster-worker/node_modules/undici/lib/dispatcher/client.js:523:3)
        at Client.<computed> (/root/cluster-worker/node_modules/undici/lib/dispatcher/client.js:250:31)
        at ClientHttp2Stream.<anonymous> (/root/cluster-worker/node_modules/undici/lib/dispatcher/client-h2.js:531:22)
        at Object.onceWrapper (node:events:632:28)
        at ClientHttp2Stream.emit (node:events:530:35)

Environment

Distributor ID: Ubuntu
Description: Ubuntu 24.04.1 LTS
Release: 24.04
Codename: noble
Node: v20.18.2

Additional context

I have looked through the source code and may have a clue as to what is potentially causing this.

The error is thrown in this snippet: https://github.com/nodejs/undici/blob/c7f3d77011234fe243c317ada1398044032342cc/lib/api/api-request.js#L76-L86

As we can observe, the culprit is that the assert(this.callback) fails thus something is nullifying the callback before the onConnect is fired.

There are only two places in the rest of this file where this is done which is within the onHeader() and onError() methods. The onHeader() is likely not the culprit as well the onConnect will always fire before the onHeader due to the request lifecycle.

The onError() thus remains to be the only culprit which can be causing this where the onError is for some reason firing before the onConnect().

In fact, there seems to be a TODO: already there which potentially questions this problematic this.callback = null operation on line 146: https://github.com/nodejs/undici/blob/c7f3d77011234fe243c317ada1398044032342cc/lib/api/api-request.js#L141-L150

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.

Research direction

Start with lib/api/api-request.js around onConnect(), onHeader(), and onError(), then trace the request lifecycle through lib/core/request.js and lib/dispatcher/client-h2.js. Investigate how an upstream failure can clear the callback before onConnect() and whether the existing TODO explains the ordering. Done should include a regression case showing request failures are caught without an uncaught AssertionError.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.