pulumi: Failure to serialize a native built-in function

The below program fails when it attempts to serialize the native built-in function, isNaN. This seems wrong, though, I thought we had logic to skip serializing builtins since we don’t actually need to serialize them (they’re available in the global context).

Expected Behavior

Pulumi should skip serializing isNaN and successfully run the program. (I don’t know if whether removing isNaN from the equation simply leads to another bit of native code, and hence another failure, however…)

Current Behavior

The program fails with an error message:

   error: Error serializing '(ev, ctx, cb) => { let body; ...': api.js(210,21)

    '(ev, ctx, cb) => { let body; ...': api.js(210,21): captured
      variable 'handlers' which indirectly referenced
        function 'app': express.js(38,20): which referenced
          function 'setMaxListeners': which captured
            'NumberIsNaN', a function defined at
              function 'isNaN': which could not be serialized because
                it was a native code function.

    Function code:
      function isNaN() { [native code] }

Steps to Reproduce

Run pulumi up on this program:

const cloud = require("@pulumi/cloud-aws");
const express = require("express");
const app = express();

app.get("/", (req, res) => {
    res.send("Hello, World!");
});

const endpoint = new cloud.API("app");

endpoint.get("/{proxy+}", app);

exports.endpoint = endpoint.publish().url;

Context (Environment)

The following is a workaround for now that uses a native API Gateway endpoint if users don’t need all of Express.js:

const cloud = require("@pulumi/cloud-aws");
const endpoint = new cloud.API("app");

endpoint.get("/", (req, res) => {    res.send("Hello, World!");});
exports.endpoint = endpoint.publish().url;

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 8
  • Comments: 15

Most upvoted comments

Having this issue with just about any library I use, zod, yup, joi, validator.js, etc etc. Any updates or fixes? Or am I doing something wrong?

I had this problem when importing a zod schema from a file with this syntax:

import {z} from "zod";

export const Schema = z.object({
    user_id: z.string(),
    start_time: z.string().datetime(),
    end_time: z.string().datetime().optional(),
    notes: z.string().optional()
})

export type Schema = z.infer<typeof Schema>

I could finally fix this by wrapping the Schema in a function 🤷‍♂️

import {z} from "zod";

export const getSchema = () => {
    return z.object({
        user_id: z.string(),
        start_time: z.string().datetime(),
        end_time: z.string().datetime().optional(),
        notes: z.string().optional()
    })
}

export type Schema = z.infer<ReturnType<typeof getSchema>>

Wrapping whatever is causing the problem in a function has solved it for me. For example, it was a schema definition for which was causing the problem. I created a fn which returns the schema like getSchema()

@mmmoli the answer kind of sucks. We removed all external libraries and just use native fetch. got, axios, etc all create the serialization error.

If you have straightforward api calls, purrl by the pulumiverse team is a good alternative on the dynamic resource side: https://github.com/pulumiverse/pulumi-purrl

Adding additional context. This also shows up in Dynamic Resources because they share a serializer. Included my logs here: https://gist.github.com/jakobo/bda66c77da6f9bfd4c0cdd50392f9ce4

In my case, I’m using node 16 w/ esm, so there’s a lot more built-in functions to bump into.

Slack thread for reference

This also fails for the promise versions of fs. For example, this is fine:

import { readdirSync } from "fs";
const files = readdirSync(".");

But this fails to serialize:

import { readdir } from "fs/promises";
const files = await readdir(".");

I also faced a similar issue. Normally bundlers would introduce these native function calls , but are not getting serialised

'(ev, ctx, cb) => { let body; ...': captured
      variable 'handlers' which indirectly referenced
        'async (req, res) => { const result = ...': which referenced
          'async (pagesContext, req, cache) =>  ...': which referenced
            'async (normalizedPathname, pagesCont ...': which referenced
              function 'getPage': which referenced
                '(module2) => { if (module2 && module ...': which referenced
                  '(target, module2, desc) => { if (mod ...': which captured
                    '__getOwnPropNames', a function defined at
                      function 'getOwnPropertyNames': which could not be serialized because
                        it was a native code function.

Any tips on which part of the code in the sdk to look up. I can give it a try to fix the same. Getting some clues can help get a quick jumpstart on the issue.

Facing same issue. If we try to use any other node module which use native code then while doing pulumi up serilize step is throwing error