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/kafka@1.23.0 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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions