contentlayer: `contentlayer build` produces `TypeError: The "code" argument must be of type number. Received an instance of Object`

The error is non-fatal and still generates the documents.

Generated 9 documents in .contentlayer
TypeError: The "code" argument must be of type number. Received an instance of Object
    at process.set [as exitCode] (node:internal/bootstrap/node:124:9)
    at Cli.runExit (/home/xenfo/projects/website/node_modules/clipanion/lib/advanced/Cli.js:232:26)
    at run (file:///home/xenfo/projects/website/node_modules/@contentlayer/cli/src/index.ts:39:3)
    at main (/home/xenfo/projects/website/node_modules/contentlayer/bin/cli.cjs:5:3) {
  code: 'ERR_INVALID_ARG_TYPE'
}

Contentlayer config:

import { defineDocumentType, makeSource } from 'contentlayer/source-files';

export const Post = defineDocumentType(() => ({
  name: 'Post',
  filePathPattern: 'posts/*.mdx',
  contentType: 'mdx',
  fields: {
    title: {
      type: 'string',
      description: 'The title of the post',
      required: true
    },
    description: {
      type: 'string',
      description: 'The description of the post',
      required: true
    },
    publishedOn: {
      type: 'date',
      description: 'The publishing date of the post',
      required: true
    },
    editedOn: {
      type: 'date',
      description: 'The editing date of the post',
      required: true
    },
    status: {
      type: 'enum',
      description: 'The status of the post',
      options: ['draft', 'published', 'edited'],
      required: true
    }
  },
  computedFields: {
    slug: {
      type: 'string',
      description: 'The slug of the post',
      resolve: (post) => post._raw.sourceFileName.replace(/\.mdx?$/, '')
    }
  }
}));

export default makeSource({
  contentDirPath: 'data',
  contentDirExclude: ['themes'],
  documentTypes: [Post]
});

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 5
  • Comments: 18

Most upvoted comments

Same here - issue occuring on Node v20.5.0. DOES NOT occur with Node 18.17.

So it seems the BuildCommand has been yielding an object (of type GenerateInfo) to clipanion’s Cli#runExit API which instead expects an exit code number.

I suspect this has gone unnoticed for so long due to the now legacy process.exitCode coercion behavior in Node.js. I will open a PR with my attempt at a fix, but I’ve also applied it as a patch via Yarn for now.

Here’s what the patch looks like using yarn patch:

.yarn/patches/@contentlayer-cli-npm-0.3.3-e932de1bc4.patch

diff --git a/dist/commands/BuildCommand.js b/dist/commands/BuildCommand.js
index 1cc67c8c9b28622c2391c1da70754ab99dcc35d6..27b35388b71bc8cb64463329e9b1ef251b3382b4 100644
--- a/dist/commands/BuildCommand.js
+++ b/dist/commands/BuildCommand.js
@@ -4,7 +4,7 @@ import { BaseCommand } from './_BaseCommand.js';
 class BuildCommand extends BaseCommand {
     constructor() {
         super(...arguments);
-        this.executeSafe = () => pipe(this.clearCacheIfNeeded(), T.chain(() => core.getConfig({ configPath: this.configPath })), T.tap((config) => (config.source.options.disableImportAliasWarning ? T.unit : T.fork(core.validateTsconfig))), T.chain((config) => core.generateDotpkg({ config, verbose: this.verbose })), T.tap(core.logGenerateInfo), OT.withSpan('@contentlayer/cli/commands/BuildCommand:executeSafe'));
+        this.executeSafe = () => pipe(this.clearCacheIfNeeded(), T.chain(() => core.getConfig({ configPath: this.configPath })), T.tap((config) => (config.source.options.disableImportAliasWarning ? T.unit : T.fork(core.validateTsconfig))), T.chain((config) => core.generateDotpkg({ config, verbose: this.verbose })), T.tap(core.logGenerateInfo), T.map(() => 0), OT.withSpan('@contentlayer/cli/commands/BuildCommand:executeSafe'));
     }
 }
 BuildCommand.paths = [['build']];

@Xenfo, hey, did you solve this somehow?

No, it’s annoying but I just let it happen since everything is still generated properly.

This is related to Node Deprecation DEP0164 (process.exit(code), process.exitCode coercion to integer.

This will offer a deprecation warning on Node 19.x.x, but as of Node 20.0.0, it will throw an error.

In relation to contentlayer, the CLI is attempting to assign a resulting object with documentCount’s existence as a means of coercing to a positive exit code.

Within CLI.js function runExit, assignment to process.exitCode should be a valid integer.

image

It is worth noting that this doesn’t affect functionality of CLI commands. It just impacts the ability for CLI commands to report a valid exit code, so it will always be assumed to be an error.