@mondaydotcomorg/api advertises ClientError (re-exported from
graphql-request) as a
named export of the package. Its type declarations declare it, its ESM
bundle re-exports it with export{ClientError}from"graphql-request", and
its CJS bundle does re-export it — but via a getter-style
Object.defineProperty:
Object.defineProperty(exports, "ClientError", {
enumerable: true,
get: function () { return t.ClientError; } // t = require('graphql-request')
});Node's CJS named-export static analyzer
(cjs-module-lexer) does not
detect this pattern as a named export. Combined with the missing exports
field in package.json (which forces Node ESM to resolve the CJS bundle),
the result is: TypeScript and bundlers accept the import, CJS require()
sees ClientError, but import { ClientError } from '@mondaydotcomorg/api'
under Node native ESM throws a SyntaxError.
@mondaydotcomorg/api@14.0.0- Node 24.8.0 (any current Node version exhibits the same behavior — the static-analyzer limitation is long-standing)
npm install
npm run repro:esm-native # ← fails with SyntaxError
npm run repro:cjs # ← passes; ClientError IS exported, just via a getter
npm run repro:typecheck # ← passes; types claim ClientError is exportednpm run show:package-fields # no `exports` field; main=CJS, module=ESM
npm run show:cjs-named-exports # CJS file's direct exports.X assignments
# (note: ClientError is absent — it's exported
# via Object.defineProperty + getter, not direct assignment)
npm run show:esm-clienterror-export # ESM bundle re-exports ClientError directly
npm run show:dts-clienterror-export # .d.ts declares ClientError as a named exportApiClient: function
ClientError: function
node:internal/modules/esm/module_job:254
import { ApiClient, ClientError } from '@mondaydotcomorg/api';
^^^^^^^^^^^
SyntaxError: Named export 'ClientError' not found. The requested module
'@mondaydotcomorg/api' is a CommonJS module, which may not support all
module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from '@mondaydotcomorg/api';
const { ApiClient, ClientError } = pkg;
The suggested workaround does work for ClientError specifically (the
getter is invoked when the property is accessed), but it forces every
consumer of @mondaydotcomorg/api to rewrite their imports — and only
because of this one re-export.
The simplest fix: change the CJS bundle so ClientError is exported via a
direct assignment that cjs-module-lexer recognizes:
// Replace the getter-based re-export …
Object.defineProperty(exports, "ClientError", {
enumerable: true,
get: function () { return t.ClientError; }
});
// …with a direct assignment:
exports.ClientError = t.ClientError;This appears to come from the Rollup configuration that produces the CJS
build — likely a preserveModules/output.exports or output.interop
quirk specific to re-exports from a transitive dependency. Other named
exports of @mondaydotcomorg/api (e.g. ApiClient) use the direct
exports.X = … form and work fine.
This is the modern convention for dual-format packages and would route
Node's native ESM loader to the ESM bundle (which already re-exports
ClientError correctly):
{
"exports": {
".": {
"types": "./dist/esm/index.d.ts",
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js"
}
}
}The legacy module field is bundler-only and has no effect on Node.
- TypeScript (any
moduleResolution) reads the.d.ts, seesexport { ClientError } from 'graphql-request';, and emits no diagnostic. - Vitest / Vite / webpack prefer the
modulefield, so they receive the ESM bundle that re-exportsClientErrordirectly — tests pass. - CJS consumers (
require('@mondaydotcomorg/api').ClientError) work fine because property access triggers the getter. - Only Node's native ESM loader trips on this, because its CJS-named-export detection is purely static and doesn't execute the getter to discover the binding. The failure typically surfaces at server boot, after CI is already green.