Skip to content

Docker image quay.io/jupyterhub/jupyterhub:5.3.0-18 is broken due to an incompatible transitive dependency (@so-ric/colorspace) not supported by Node.js 12. #40

@ykazakov

Description

@ykazakov

Note: The report is generated with the help of AI

Bug description

The Docker image with tag 5.3.0-18 (and 5.3.0) fails to start, throwing a SyntaxError: Unexpected token '='. This error originates from configurable-http-proxy and is caused by modern JavaScript syntax (||=) in one of its transitive dependencies.

This is a regression, as the previous image tag 5.3.0-17 works correctly with the exact same versions of Node.js and configurable-http-proxy.

The root cause appears to be a non-deterministic npm install during the Docker build process, which pulled a newer, incompatible version of a sub-dependency in the -18 build compared to the -17 build.

How to reproduce

  1. Pull the latest 5.3.0 tag or the specific 5.3.0-18 tag.
  2. Attempt to run any command that invokes configurable-http-proxy, including checking its version.
  3. The command will fail with a syntax error.
# This command immediately fails
$ docker run -it --rm quay.io/jupyterhub/jupyterhub:5.3.0-18 configurable-http-proxy --version
/usr/local/lib/node_modules/configurable-http-proxy/node_modules/@so-ric/colorspace/dist/index.cjs.js:1976
                (limiters[m] ||= [])[channel] = modifier;
                               ^

SyntaxError: Unexpected token '='
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:85:18)
    at Object.<anonymous> (/usr/local/lib/node_modules/configurable-http-proxy/node_modules/@dabh/diagnostics/modifiers/namespace-ansi.js:1:18)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)

Analysis & Evidence

A direct comparison between the working (-17) and failing (-18) images reveals the following:

  • Node.js Version (Identical in Both): v12.22.9
  • configurable-http-proxy Version (Identical in Both): 4.6.3

The critical difference lies in a transitive dependency of configurable-http-proxy:

  • In the working -17 image, the dependency resolved to colorspace@1.1.4:

    $ docker run -it --rm quay.io/jupyterhub/jupyterhub:5.3.0-17 /bin/bash \
      -c "npm list -g --depth=Infinity | grep 'colorspace'"
        │ ├─┬ colorspace@1.1.4
  • In the failing -18 image, the dependency resolved to a newer, scoped package @so-ric/colorspace@1.1.6:

    $ docker run -it --rm quay.io/jupyterhub/jupyterhub:5.3.0-18 /bin/bash \
      -c "npm list -g --depth=Infinity | grep 'colorspace'"
    │ ├─┬ @so-ric/colorspace@1.1.6

Proof of Incompatibility

The root of the SyntaxError is the use of the logical OR assignment (||=) operator in the source code of @so-ric/colorspace.

This operator is a modern JavaScript feature (part of ECMAScript 2021) and is not supported by the Node.js v12 runtime provided in the Docker image. According to the official Mozilla Developer Network (MDN) documentation, support for this feature in Node.js was not added until version 15.0.0.

Reference: The MDN compatibility table for Logical OR assignment (||=) confirms the required Node.js version.

Since the image uses Node.js v12.22.9, its JavaScript engine cannot parse this syntax, which directly causes the crash.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions