DSH plugin: the real cause of failed to import on process/

TroubleshootingPublished 2026-10-03Author: DeepSeek Plugin Market
DeepSeek HarnessDSHdsh-app-bootCJS resolutionrequire.resolve.pathsfailed to importplugin loadingResolutionRouter
With a CJS-dependency plugin, DSH startup prints only failed to import with no reason: the CJS resolution hook strips the request to a bare name and crashes.

After installing a plugin with a CJS dependency, the DSH startup log gives you just two lines, with not a word of reason: dsh: warning: 1 entry did not activate and whale_craft (whale_craft): failed to import. The real error was swallowed by the host, and only a probe plugin in the loader context could retrieve it:

text
TypeError: createRequire.resolve.paths is not a function or its return value is not iterable
    at ResolutionRouter.routeScoped (…/@deepseek-ai/dsh-app-boot/lib/index.js:1422:58)

The real cause is not "that API does not exist" but that its return value is null: the triggering plugin readable-stream@4.7.0 writes require('process/') (note the trailing slash), so isBuiltin('process/') is false and it enters the resolution route normally; DSH then uses barePackageName() to strip the request down to the bare package name process before asking resolve.paths(), hitting Node's "core modules return null" semantics, and for…of null crashes immediately (#8674). And V8 merges the two situations "is not a function" and "its return value is not iterable" into the same error message, making that hint extremely misleading — it took us three rounds to locate it. More importantly: 0.2.0-rc.2 and master are both still unfixed, so upgrading does not help (#8674). Below we go "triage first → root cause → the localization process → version matrix → fixes → minimal reproduction", with paste-ready code and re-runnable commands throughout.

Triage first: why failed to import gives no reason, and how to get it yourself

Key conclusion: this is not a missing dependency, and the plugin is not written wrong — under native Node that require('process/') resolves perfectly fine. But before suspecting anything, force the swallowed error out.

1. Understand the log's limitation

When the host encounters fiber === undefined in inactiveEntries(), it records only:

text
dsh: warning: 1 entry did not activate
whale_craft (whale_craft): failed to import

The underlying import exception is discarded entirely. That is, the log can only tell you "which entry did not activate", never "why".

2. Use a probe plugin to write the real error out

Write a minimal probe plugin, have it declare dsh.bundle.patch so it loads as a bundle, then try imports one by one in the loader context and write the exceptions to a file:

js
// profile/node_modules/<probe>/index.js
import { appendFileSync } from 'node:fs'

const OUT = '<somewhere>/probe-result.txt'
const log = (s) => { try { appendFileSync(OUT, s + '\n') } catch {} }

for (const spec of [
  '@deepseek-ai/schemastery',
  '@deepseek-ai/dsh-tools',
  '@deepseek-ai/dsh-llm',
  'mineflayer',
  'whale_craft',
]) {
  try {
    await import(spec)
    log(`OK   ${spec}`)
  } catch (error) {
    log(`FAIL ${spec}`)
    log(String((error && (error.stack || error.message)) || error))
  }
}

export const name = 'probe'
export function apply() {}

The result is informative: all host packages are OK, and failures concentrate on mineflayer and its dependency chain, with the real error being that TypeError ... lib/index.js:1422 above. Once localized to this point, the direction shifts from "is the plugin broken" to "what does the host's resolution hook do on this chain".

3. One command to separate "missing dependency" from "host resolution problem"

Both symptoms look like "some require failed", but their fixes are completely different. Three lines of plain Node separate them:

js
const { createRequire } = require('node:module')
const req = createRequire('C:/any/dir/parent.js')

console.log(req.resolve.paths('process'))    // null        ← builtin name
console.log(req.resolve.paths('process/'))   // 18 search chains  ← a slash bypasses the builtin check
console.log(req.resolve('process/'))         // …/node_modules/process/index.js

The third line resolves a real node_modules/process/index.js, which shows the package is installed and native resolution works — the problem is not the dependency but the host's resolution route.

Root cause: after stripping the slash, the request becomes "a query for a core module name"

In one sentence: resolve.paths() returns null for a core module name, and the call site directly does for…of, hence the TypeError.

1. The crash point

ResolutionRouter.routeScoped in @deepseek-ai/dsh-app-boot (line 1422 in 0.1.7-rc.2):

js
for (const searchPath of createRequire(parent).resolve.paths(name)) {   // ← crashes here

Unfolding this chain gives:

text
readable-stream@4.7.0  lib/internal/streams/end-of-stream.js:8
    const process = require('process/')      ← trailing slash; the package's dependencies really do include process
        │
        ├─ isBuiltin('process/') === false   → not caught as a builtin module, enters the resolution route normally
        │
        └─ barePackageName('process/') === 'process'   → stripped to a bare package name
                │
                └─ resolve.paths('process') === null   → hits the "core module" branch
                        │
                        └─ for (… of null)  → TypeError

2. That misleading error

For "a call expression inside for-of", V8 merges two entirely different situations into one sentence:

text
TypeError: createRequire.resolve.paths is not a function or its return value is not iterable

The API the error text points at actually exists; the real cause is that the return value is not iterable (it is null). It was precisely this merger that cost two extra rounds of troubleshooting (first suspecting the monkey-patch did not carry resolve.paths, then suspecting createRequire was used wrongly).

3. Measured data (Node v26.7.0 / win32)

ExpressionResult
resolve.paths('process')null
resolve.paths('process/')18 search chains
resolve.paths('fs')null
resolve.paths('fs/')18 search chains
resolve.paths('mineflayer')a normal array (non-builtin names are unaffected)
resolve('process/')<profile>\node_modules\process\index.js ✅

The pattern is very clean: builtin name → null, builtin name with a slash → a full search chain, ordinary package name → a normal array.

4. Why ?? [] is not enough (the second pitfall)

The same-shaped call at line 883 of the same file carries ?? []; the other call sites missed it. But measurement shows that merely supplying an empty array only changes the error's appearance while it persists:

text
// after adding only ?? []
Error: Cannot find module 'process/'

The reason is that localSearchPaths becomes an empty array → cjs.resolveNative([]) fails → that require still fails. You must provide a correct search chain; you cannot just fall back to empty.

5. Where the same-shaped code is distributed

Same-shaped code in the same file is also at 1247 / 1475 / 2019 / 3263; on the worker side, lib/worker/profile-resolution-bootstrap.js lines 310 / 363 as well. The local workaround patch covers 9 call sites across two files — fixing only the crashing line means other chains will reproduce it again.

The localization process: four steps, reusable for anyone hitting a similar problem

The value of this section is the process, not the conclusion. The starting point is ordinary: install a plugin with a CJS dependency → startup yields only one line, failed to import, with no reason.

  1. Force the swallowed error out. The error is inside the loader and invisible in normal logs. Write a probe plugin (declaring dsh.bundle.patch so it loads as a bundle), do try { await import(spec) } catch (e) { write a file } in the loader context, and try @deepseek-ai/schemastery, dsh-tools, mineflayer, and the target plugin itself one by one. Result: host packages are OK, mineflayer and its dependency chain fail, and the real error is a TypeError ... (pointing at lib/index.js:1422).
  2. Try the conventional fallback first, and find it insufficient. Adding ?? [] to that loop moves the error on to Cannot find module 'process/' — showing the search chain got emptied and supplying an empty array is the wrong direction.
  3. Ask Node for the facts directly. Two measured calls: resolve.paths('process') → null; resolve.paths('process/') → 18 search chains. The root cause is now clear, and it also explains why that error is misleading.
  4. Verify the fix and check upstream. Write the guard dshResolvePaths() (retry with a slash if it cannot get a value) and replace all call sites → the plugin loads normally; then set up a minimal home (only readable-stream + the probe) and compare against 0.2.0-rc.2, confirming the latest release is hit too.

Two lessons are worth recording on their own:

  • The host swallows the real import exception into one sentence, making troubleshooting an order of magnitude more expensive; even carrying the underlying exception only under DSH_DEBUG=1 would save step 1 above.
  • Type assertions mask runtime risk: in master those calls are written resolve.paths(name) as string[]; as is a compile-time lie, and null at runtime passes through the type check just the same.

Version matrix: this is not a "just upgrade" problem

The conclusion first: 0.1.7-rc.2 reproduces by measurement, 0.2.0-rc.2 (npm's latest release) reproduces on a real machine and is unfixed, and the master source is equally unfixed.

VersionConclusionBasis
0.1.7-rc.2reproduces by measurementstarting whale_craft on this machine gives failed to import; the probe gets the TypeError (lib/index.js:1422)
0.2.0-rc.2 (npm's latest release)reproduces on a real machine, unfixed① a line-by-line diff against 0.1.7-rc.2: only 1 hunk, and it is an unrelated bundle-list addition (@deepseek-ai/dsh-experimental-schedule-bundle); the 63-line body of routeScoped is byte-for-byte identical; the unguarded resolve.paths(name) is still at 1248 / 1423 / 1476 / 2020 / 3264. ② real-machine verification with a minimal home: still the same TypeError and the same call stack, only the line number becomes 1423
master (source)equally unfixedpackages/boot/app-boot/src/profile-resolution/resolver.ts lines 244 / 471 / 524 are the same shape, only with an extra as string[] assertion; the whole file has 0 occurrences of Array.isArray, and no ?? at those call sites. And that file's most recent change is 2026-09-23, untouched since
Release recordsno related fixthe latest tag is dsh-v0.2.0-rc.2; the release notes do not mention resolve.paths / CJS resolution

This is not a new problem. Searching the discussions for resolve.paths gives 19 results, of which at least 5 are same-origin reports with different triggering packages, spanning 0.1.6-alpha to 0.1.7-rc.2, and not one has received a fix or a maintainer response:

#DateTrigger chainHighlight
#703109-18jsdom → whatwg-url → tr46 → require("punycode/")the earliest; already notes that "locally adding ?? [] moves the error to Cannot find module 'punycode/'"; 0.1.6-alpha.1 vs .2 comparison
#737709-21 (+09-30 comment)ExcelJS → process/ (plus string_decoder/)gives a three-line minimal reproduction; the 09-30 update: 0.2.0-rc.2 (desktop) is still affected
#790309-26jsdom → … → punycode/states explicitly that "the 0.1.7-rewritten ResolutionRouter no longer guards resolve.paths()"; 0.1.5-rc.2 works vs 0.1.7-rc.2 fails
#791109-26a top-level call to createRequire(...).resolve.paths()explains "the hijacked require.resolve does not carry the native resolve.paths"; names whale_craft and line 1422
#825009-29the static dependency msedge-ttsprobe-style per-package bisection; points out the environment difference "a fresh DSH_HOME works, an old home fails"

A methodological lesson to note in passing: the reporter's first draft said "nobody has reported this before", because they only used GitHub's REST search (which covers only issues and PRs) and got 0 hits — REST search does not cover Discussions. Switching to a discussions search yielded 19. To judge "has someone already reported this" on GitHub, you must include Discussions.

Fixes: three guards, from the smallest change to the long-term direction

Fix A (smallest change, 1 line): retry with a slash

js
const paths = resolve.paths(name) ?? resolve.paths(name + "/")

Measured, this gives 18 search chains. The principle is that the trailing slash stops the name from being judged a core module, so it goes back to the normal search-chain computation.

Fix B: fall back to Node's own algorithm

js
const paths = resolve.paths(name) ?? Module._nodeModulePaths(dirname(parent))

Measured, this yields 15 search chains. The rest of that file already uses _nodeModulePaths, so this is stylistically consistent.

Fix C (a local workaround patch): a unified guard function, replacing all call sites

Replace every createRequire(x).resolve.paths(y) in the two files with the guarded version:

js
/**
 * Guard against require.resolve.paths' two failure modes:
 *   1) the function does not exist → return the fallback
 *   2) it returns null (a core module name) → retry with a slash to bypass the builtin check
 * Note: you cannot just `?? []`, or the same require moves on to Cannot find module.
 * Modeled on the guard in jestjs/jest#16052.
 */
function dshResolvePaths(req, name) {
  try {
    const resolvePaths = req && req.resolve && req.resolve.paths
    if (typeof resolvePaths === 'function') {
      const value = resolvePaths.call(req.resolve, name)
      if (Array.isArray(value)) return value
      const retry = resolvePaths.call(req.resolve, name + '/')   // ← bypass the builtin check
      if (Array.isArray(retry)) return retry
    }
  } catch {
    /* if nothing can be obtained, let the caller fall back to native resolution */
  }
  return []
}

Integration notes:

  • 0.1.7-rc.2 has 9 spots, across lib/index.js and lib/worker/profile-resolution-bootstrap.js;
  • 0.2.0-rc.2 corresponds exactly (lib/index.js line numbers +1), rewritten the same way;
  • This edits the host runtime files, so a DSH upgrade overwrites it (the new version directory is a separate copy) and it must be re-patched;
  • Once upstream is fixed, delete it; the patch only affects the resolution fallback path, and when resolve.paths() returns an array normally its behavior is identical to upstream.

Measured effect after patching

PhaseResult
Before patchingonly dsh: warning: 1 entry did not activate + whale_craft (whale_craft): failed to import (the real error swallowed)
After patchingthe probe reports OK item by item: @deepseek-ai/schemastery / dsh-tools / dsh-llm / mineflayer / whale_craft; no more failed to import in the startup log; the plugin's own log shows "plugin loaded

Long-term direction: stop monkey-patching Module._resolveFilename

This kind of monkey-patch of the CJS resolver has known ecosystem risks, and the official replacement is:

js
// stable in Node ≥22.15 / 24
import { registerHooks } from 'node:module'
registerHooks({ resolve(/* … */) { /* … */ } })

Minimal reproduction: two kinds, neither depending on a specific plugin

To report to maintainers, or to confirm "is this the same thing", use either of the following; it runs in two minutes.

Way one: a zero-dependency, cross-machine plain Node script

js
#!/usr/bin/env node
import { createRequire, _nodeModulePaths } from 'node:module'
import { dirname } from 'node:path'
import { fileURLToPath } from 'node:url'

const argv = process.argv.slice(2)
const parentArg = argv.indexOf('--parent')
const parent = parentArg >= 0 && argv[parentArg + 1] ? argv[parentArg + 1] : fileURLToPath(import.meta.url)

const req = createRequire(parent)
const line = (label, value) => console.log(`  ${label.padEnd(34)} → ${value}`)

console.log('① key data (this is the root cause)')
for (const name of ['process', 'process/', 'fs', 'fs/']) {
  const value = req.resolve.paths(name)
  line(`resolve.paths(${JSON.stringify(name)})`,
    Array.isArray(value) ? `${value.length} search chains` : String(value))
}

console.log('\n② native resolution itself is fine (so this is not a missing dependency)')
try { line("resolve('process/')", req.resolve('process/')) }
catch (error) { line("resolve('process/')", `${error.code ?? error.name}: no process package installed here (does not affect the conclusion)`) }

console.log('\n③ replicate DSH\'s code: strip to a bare package name then for...of directly')
const bare = 'process'   // barePackageName('process/')
try {
  for (const searchPath of req.resolve.paths(bare)) void searchPath
  console.log('  …did not crash (this environment differs from the reported one)')
} catch (error) {
  line('for (… of resolve.paths(bare))', `${error.constructor.name}: ${error.message}`)
}

console.log('\n④ two suggested fixes (both yield an iterable search chain)')
const fixedA = req.resolve.paths(bare) ?? req.resolve.paths(`${bare}/`)
line('A. paths ?? resolve.paths(name + "/")', Array.isArray(fixedA) ? `${fixedA.length} search chains ✅` : String(fixedA))
const fixedB = req.resolve.paths(bare) ?? _nodeModulePaths(dirname(parent))
line('B. paths ?? _nodeModulePaths(dirname)', Array.isArray(fixedB) ? `${fixedB.length} search chains ✅` : String(fixedB))

console.log('\n⑤ counterexample: adding only `?? []` is not enough')
const empty = req.resolve.paths(bare) ?? []
line('search-chain length from paths ?? []', `${empty.length}  ← with an empty search chain, the same require becomes Cannot find module`)

How to run (--parent can point at any file deep inside node_modules):

bash
node repro-resolve-paths.mjs --parent ".../node_modules/readable-stream/lib/internal/streams/end-of-stream.js"

Local output (Node v26.7.0 / win32):

text
① key data (this is the root cause)
  resolve.paths("process")           → null
  resolve.paths("process/")          → 18 search chains
  resolve.paths("fs")                → null
  resolve.paths("fs/")               → 18 search chains
③ replicate DSH's code: strip to a bare package name then for...of directly
  for (… of resolve.paths(bare))     → TypeError: req.resolve.paths is not a function or its return value is not iterable
⑤ counterexample: adding only `?? []` is not enough
  search-chain length from paths ?? []  → 0  ← with an empty search chain, the same require becomes Cannot find module

Way two: a minimal-profile reproduction (goes through the real loader, no third-party plugin)

Four steps to build a clean home:

  1. Create the directory <home>/profiles/web/plugins/cjs-probe/;
  2. Write the profile's package.json:
json
{
  "name": "dsh-profile-web",
  "private": true,
  "dependencies": {
    "readable-stream": "4.7.0",
    "cjs-probe": "file:plugins/cjs-probe"
  },
  "dsh": {
    "profile": {
      "bundles": [
        "@deepseek-ai/dsh-base",
        "@deepseek-ai/dsh-web-app",
        "cjs-probe"
      ]
    }
  }
}
  1. Write the probe trio — index.js does require('readable-stream') and writes exceptions to a file; package.json must declare dsh.bundle.patch, or the bundle is not loaded:
json
{
  "name": "cjs-probe",
  "version": "0.0.1",
  "private": true,
  "type": "module",
  "main": "index.js",
  "dsh": { "bundle": { "patch": "./cordis.patch.yml" } }
}
yaml
# cordis.patch.yml
- insert:
    - id: cjs-probe
      name: cjs-probe
js
// index.js
import { appendFileSync } from 'node:fs'
import { createRequire } from 'node:module'

const OUT = '<somewhere>/minimal-result.txt'
const log = (s) => { try { appendFileSync(OUT, s + '\n') } catch {} }
log(`===== cjs-probe @ ${new Date().toISOString()} =====`)

const req = createRequire(import.meta.url)
try {
  const rs = req('readable-stream')
  log('OK   require("readable-stream") succeeded  version=' + (rs && rs.Writable ? 'has Writable' : '?'))
} catch (e) {
  log('FAIL require("readable-stream")')
  log(String((e && (e.stack || e.message)) || e))
}

export const name = 'cjs-probe'
export function apply() {}
  1. Install dependencies and start:
bash
pnpm install --dir <home>/profiles/web --node-linker=hoisted      # point store at your own
DSH_HOME=<home> node <dsh>/lib/bin.js --profile web --port 3399

Expected: the result file contains

text
TypeError: createRequire.resolve.paths is not a function or its return value is not iterable
    at ResolutionRouter.routeScoped (…/@deepseek-ai/dsh-app-boot/lib/index.js:1423:58)   # 1422 in 0.1.7

0.2.0-rc.2 reproduces on a plain start (same stack), so upgrading to the latest release does not avoid it.

Troubleshooting notes

  1. failed to import does not equal "the plugin itself has a bug". First find the CJS package in its dependency chain, then look at the host resolution hook.
  2. Treat TypeError: X is not a function or its return value is not iterable as two hypotheses to verify separately: in this case the function exists; it is the return value (null) that crashes.
  3. Do not stop at ?? []. It turns the TypeError into Cannot find module, which looks like "a different error" but is the same pit.
  4. resolve.paths()'s return value has three possibilities: an array, null (a core module), or the function not existing (hijacked). The guard must cover all three.
  5. Fixing only the crashing line is not enough. Same-shaped code sits at 9 spots across two files; replacing it must cover all.
  6. Watch for compile-time assertions like as string[]. They let null pass the type check, the direct reason this class of bug survives so long.
  7. Editing host runtime files gets overwritten by upgrades. Record the patch locations, re-patch after upgrading, and delete it once upstream is fixed.
  8. Search Discussions when judging "has anyone reported this". REST search covers only issues/PRs and misses an entire class of reports.
  9. Attach a re-runnable script when reporting. For a problem like this that only triggers with a specific plugin installed, a zero-dependency reproduction script significantly raises the odds of it being handled.
  10. Diagnostic tools like dsh-why may not recognize this pattern yet (its current rule base covers only the client module-table class of errors). The discriminator is: the error mentions resolve.paths, and the plugin has a CJS dependency.

When troubleshooting "a plugin installs but will not load", the most troublesome part is usually confirming which plugin, which version, and which dependency chain is at fault — especially when the startup log gives only one failed to import. DSH Plugin Hub provides five screens: plugin market, installed list, custom install, settings, and system logs. The installed list labels each plugin's source (catalog plugin / custom install), version number, and update time, and can locate the install directory directly; the system log page records install, uninstall, and diagnostic trails by category and level, with full-text export. Use it to align "what is installed, at what version, and where" first, then investigate resolution problems chain by chain — it saves a lot of back and forth.

DSH Plugin Hub · Installed plugin list: filter by source, show version and update time, and locate directly in the file manager

Source: Discussion #8674, #7031, #7377, #7903, #7911, #8250, guard modeled on jestjs/jest#16052, monkey-patch blast radius in nub — Monkey-patching of Node's CJS resolver.

FAQ

The plugin only reports `failed to import` at startup, with no reason — how do I dig out the real error?

Write a "probe plugin": have it declare dsh.bundle.patch so it is loaded as a bundle, then in the loader context do try { await import(spec) } catch (e) { write e.stack to a file }, trying host packages (like @deepseek-ai/schemastery, dsh-tools), the target plugin itself, and packages on its dependency chain one by one. Host packages are usually OK, and the failures concentrate on the chain with the CJS dependency. This is necessary because the host records only error: "failed to import" when fiber === undefined; the real import exception is discarded and not visible in normal logs.

Why does `resolve.paths()` return null? It is not that Node's API is broken, is it?

No. Node's documentation states clearly that require.resolve.paths(request) returns null when request is a **core module**. The key here is the name being queried: the trigger writes require('process/') — **with a trailing slash** — so it is not caught by isBuiltin() and enters the route normally; and once DSH uses barePackageName(request) to strip it down to the bare package name process before asking for paths, it hits the "core module" branch and gets null, after which for…of null throws a TypeError. The root cause is that the host is missing a guard, not that the API is misbehaving.

Can't I just add `?? []` before the loop?

No — that is a dead end we actually walked down. With ?? [], the error changes from TypeError to Error: Cannot find module 'process/' — because the search chain is emptied, cjs.resolveNative([]) gets no candidate paths, and that require still fails. **You must fall back to a real search chain**: either retry with a slash appended to the name (resolve.paths(name + "/"), measured 18 chains), or use Node's own algorithm (Module._nodeModulePaths(dirname(parent)), measured 15 chains).

Will upgrading to the latest version solve it?

No. A line-by-line diff of 0.2.0-rc.2 against 0.1.7-rc.2 has only 1 hunk, and it is an unrelated bundle-list addition (@deepseek-ai/dsh-experimental-schedule-bundle); the 63-line body of routeScoped is **byte-for-byte identical**, and the unguarded resolve.paths(name) is still there (lines 1248 / 1423 / 1476 / 2020 / 3264). Starting 0.2.0-rc.2 with a minimal home (only readable-stream@4.7.0 + one probe plugin) still throws the same TypeError and the same call stack, only with the line number changing from 1422 to 1423. The master source is equally unfixed.

Does this bug only affect `readable-stream`? Can't I just switch plugins?

There is more than one trigger. Searching the discussions for resolve.paths yields 19 results, of which at least 5 are same-origin reports with different trigger chains: jsdom → whatwg-url → tr46 → require("punycode/"), ExcelJS → process/ (plus string_decoder/), the static dependency tree of msedge-tts, and more, spanning 0.1.6-alpha to 0.1.7-rc.2, none of which received a fix. The common trait is "has a CJS dependency, and the dependency chain does a slash-suffixed require of a builtin module name". So switching plugins only avoids this one trigger; it cannot fix the host.

Related Terms

require.resolve.paths(request)
Node's CJS resolution API, returning the array of "which directories will be searched in turn when resolving request from the current parent module's location"; **it returns `null` when request is a core module**. Precisely because the return value can be `null` rather than an empty array, any code that directly does `for…of` must check the type after obtaining the value.— https://github.com/deepseek-ai/deepseek-harness/discussions/8674
barePackageName()
The function in DSH's resolution route that normalizes a request into a "bare package name": `'process/'` → `'process'`. It erases the trailing slash, and with it the side effect of `isBuiltin('process/') === false` that "bypasses the builtin check" — before stripping, the request can be routed as an ordinary package; after stripping, it becomes a query for a core module name.— https://github.com/deepseek-ai/deepseek-harness/discussions/8674
ResolutionRouter.routeScoped
The routing function in `@deepseek-ai/dsh-app-boot` that decides "which scope a given require should search under" (0.1.7-rc.2 `lib/index.js:1422`, corresponding to 1423 in 0.2.0-rc.2). It hooks into the CJS resolution chain by monkey-patching `Module._resolveFilename`. The crash point in this article is its internal `for…of` over `createRequire(parent).resolve.paths(name)`.— https://github.com/deepseek-ai/deepseek-harness/discussions/8674
the swallowed exception (failed to import)
When the host encounters `fiber === undefined` in `inactiveEntries()`, it records only `error: "failed to import"` with no underlying exception. The consequence is that the startup log has only two lines with no reason at all (`1 entry did not activate` + `failed to import`), and the real TypeError is entirely invisible — making troubleshooting an order of magnitude more expensive; in this case merely obtaining that sentence took three rounds (a probe plugin + a stepwise guard).— https://github.com/deepseek-ai/deepseek-harness/discussions/8674

Sources