Skip to content

infinite loop hang in import loader #245

@trentm

Description

@trentm

There is a possible infinite loop in the import loader.

Repro:

% node --version; npm --version
v24.13.0
11.9.0

% cat package.json
{
  "name": "iitm-infinite-loop",
  "main": "loopy.mjs",
  "scripts": {
    "start": "NODE_DEBUG=* node --experimental-loader=import-in-the-middle/hook.mjs --trace-warnings loopy.mjs"
  },
  "dependencies": {
    "import-in-the-middle": "3.0.0",
    "@platformatic/kafka": "1.22.0"
  }
}

% cat loopy.mjs
import { Producer } from "@platformatic/kafka"

% npm i
...

Run it and it hangs (high CPU usage, I think it eventually runs out of memory):

`npm start` output
% npm start

> start
> NODE_DEBUG=* node --experimental-loader=import-in-the-middle/hook.mjs --trace-warnings loopy.mjs

WORKER 94951: [0] create new worker internal/modules/esm/worker {
  stderr: false,
  stdin: false,
  stdout: false,
  trackUnmanagedFds: false,
  workerData: {
    lock: SharedArrayBuffer {
      [Uint8Contents]: <00 00 00 00>,
      [byteLength]: 4
    }
  }
} isInternal: true
WORKER 94951: instantiating Worker. url: node:internal/modules/esm/worker doEval: internal
WORKER 94951: [0] created Worker with ID 1
STREAM 94951: pipe count=1 opts=undefined
STREAM 94951: resume
STREAM 94951: pipe count=1 opts=undefined
STREAM 94951: resume
ASYNC_LOADER_WORKER 94951: wait for signal from worker
ASYNC_LOADER_WORKER 94951: post sync message to worker {
  method: 'resolve',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    undefined,
    [Object: null prototype] {}
  ],
  transferList: undefined
}
ASYNC_LOADER_WORKER 94951: wait for sync response from worker {
  method: 'resolve',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    undefined,
    [Object: null prototype] {}
  ]
}
ASYNC_LOADER_WORKER 94951: got sync message from worker {
  method: 'resolve',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    undefined,
    [Object: null prototype] {}
  ],
  response: undefined
}
ASYNC_LOADER_WORKER 94951: wait for sync response from worker {
  method: 'resolve',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    undefined,
    [Object: null prototype] {}
  ]
}
ASYNC_LOADER_WORKER 94951: got sync message from worker {
  method: 'resolve',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    undefined,
    [Object: null prototype] {}
  ],
  response: { message: { status: 'success', body: [Object] } }
}
ASYNC_LOADER_WORKER 94951: post sync message to worker {
  method: 'load',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {
      format: 'module',
      importAttributes: [Object: null prototype] {}
    }
  ],
  transferList: undefined
}
ASYNC_LOADER_WORKER 94951: wait for sync response from worker {
  method: 'load',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {
      format: 'module',
      importAttributes: [Object: null prototype] {}
    }
  ]
}
ASYNC_LOADER_WORKER 94951: got sync message from worker {
  method: 'load',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {
      format: 'module',
      importAttributes: [Object: null prototype] {}
    }
  ],
  response: undefined
}
ASYNC_LOADER_WORKER 94951: wait for sync response from worker {
  method: 'load',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {
      format: 'module',
      importAttributes: [Object: null prototype] {}
    }
  ]
}
ASYNC_LOADER_WORKER 94951: got sync message from worker {
  method: 'load',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {
      format: 'module',
      importAttributes: [Object: null prototype] {}
    }
  ],
  response: { message: { status: 'success', body: [Object] } }
}
ESM 94951: Translating StandardModule file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs [Object: null prototype] {
  format: 'module',
  responseURL: 'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
  source: Uint8Array(47) [
    105, 109, 112, 111, 114, 116,  32, 123, 32,
     80, 114, 111, 100, 117,  99, 101, 114, 32,
    125,  32, 102, 114, 111, 109,  32,  34, 64,
    112, 108,  97, 116, 102, 111, 114, 109, 97,
    116, 105,  99,  47, 107,  97, 102, 107, 97,
     34,  10
  ],
  translatorKey: 'module'
}
ESM 94951: Storing file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs (implicit type) in ModuleLoadMap
ASYNC_LOADER_WORKER 94951: post sync message to worker {
  method: 'resolve',
  args: [
    '@platformatic/kafka',
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {}
  ],
  transferList: undefined
}
ASYNC_LOADER_WORKER 94951: wait for sync response from worker {
  method: 'resolve',
  args: [
    '@platformatic/kafka',
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {}
  ]
}
ASYNC_LOADER_WORKER 94951: got sync message from worker {
  method: 'resolve',
  args: [
    '@platformatic/kafka',
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {}
  ],
  response: undefined
}
ASYNC_LOADER_WORKER 94951: wait for sync response from worker {
  method: 'resolve',
  args: [
    '@platformatic/kafka',
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {}
  ]
}
ASYNC_LOADER_WORKER 94951: got sync message from worker {
  method: 'resolve',
  args: [
    '@platformatic/kafka',
    'file:///Users/trentm/tmp/asdf.20260203T154549/loopy.mjs',
    [Object: null prototype] {}
  ],
  response: { message: { status: 'success', body: [Object] } }
}
ASYNC_LOADER_WORKER 94951: post sync message to worker {
  method: 'load',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/node_modules/@platformatic/kafka/dist/index.js?iitm=true',
    [Object: null prototype] {
      format: 'module',
      importAttributes: [Object: null prototype] {}
    }
  ],
  transferList: undefined
}
ASYNC_LOADER_WORKER 94951: wait for sync response from worker {
  method: 'load',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/node_modules/@platformatic/kafka/dist/index.js?iitm=true',
    [Object: null prototype] {
      format: 'module',
      importAttributes: [Object: null prototype] {}
    }
  ]
}
ASYNC_LOADER_WORKER 94951: got sync message from worker {
  method: 'load',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/node_modules/@platformatic/kafka/dist/index.js?iitm=true',
    [Object: null prototype] {
      format: 'module',
      importAttributes: [Object: null prototype] {}
    }
  ],
  response: undefined
}
ASYNC_LOADER_WORKER 94951: wait for sync response from worker {
  method: 'load',
  args: [
    'file:///Users/trentm/tmp/asdf.20260203T154549/node_modules/@platformatic/kafka/dist/index.js?iitm=true',
    [Object: null prototype] {
      format: 'module',
      importAttributes: [Object: null prototype] {}
    }
  ]
}
^C

This was fixed in @platformatic/[email protected] via platformatic/kafka#191
Source issues: platformatic/kafka#191 and open-telemetry/opentelemetry-js#6203

While the platformatic/kafka case was fixed, I gather this could happen for other cases in the wild. Sorry I haven't dug into the code at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions