Summary
The published Windows x64 addon in @arcships/light-ocr@0.3.0 imports node.exe through the normal PE import directory instead of the delay-import directory.
That works when the host executable is actually node.exe, but it is not safe for renamed Node-API hosts such as Electron. In the affected Electron application the host executable is electron.exe in development and echoo.exe in production. Because neither basename satisfies the normal node.exe import, Windows resolves another node.exe from PATH. The addon then calls N-API exports in that separately mapped, uninitialized Node image and terminates the Electron process with an execute access violation.
The crash is independent of OCR image size, GPU vendor, WebGPU, and execution-provider selection. Explicit execution.provider = "cpu" crashes in the same way because the failure occurs while loading the native addon, before ONNX Runtime session creation or recognition.
Affected environment
@arcships/light-ocr: 0.3.0
- Host: Electron
37.10.0, embedded Node.js 22
- OS/architecture: Windows x64
- Application executable:
electron.exe in development, echoo.exe when packaged
- Reproduced with explicit CPU execution and an 800 x 180 fixture
Reproduction
const { createEngine } = require('@arcships/light-ocr');
await createEngine({
bundlePath,
execution: { provider: 'cpu' },
});
- Running the same package under
node.exe succeeds.
- Running it under Electron terminates the complete process before the promise settles.
- No
OcrError, rejected promise, or application-level error marker is emitted.
Evidence
- Application diagnostics end at
ocr.engine_init.start; there is no ocr.engine_init.success, ocr.engine_init.error, or recognition marker.
- A ProcDump capture reports
EXCEPTION_ACCESS_VIOLATION with execute address 0x0569e006 and process exit code 0xFFFF7003.
- The crashed process module list contains:
- the expected
light_ocr_node.node and bundled onnxruntime.dll;
- an unexpected
@archshipsdim-desktop\\runtime\\node\\node.exe loaded from PATH.
- PE inspection of the published addon shows
node.exe in its normal import directory with the required N-API symbols.
- Electron's executable exports all N-API symbols required by the addon, but its basename does not match the normal
node.exe import.
- Rebuilding the addon with
node.exe delay-loaded and a host redirection hook makes the same Electron 37 CPU OCR smoke recognize HELLO 123 successfully.
Root cause
Linking a Windows Node-API addon with node.lib is normal; the import library commonly records node.exe as the provider of Node/N-API exports. The defect is that this addon leaves node.exe as a normal import and does not link an effective Windows delay-load hook.
Node-API provides ABI stability, but it does not by itself redirect a normal PE import to a differently named host executable. Electron-compatible Windows addons must delay-load node.exe and redirect that request to the current host module, following the established win_delay_load_hook pattern.
Expected behavior
The same Windows .node artifact should load under supported Node-API hosts without assuming that the host executable basename is node.exe. Failure should reject with a structured error rather than loading an unrelated executable from PATH or terminating the process.
Proposed upstream fix
- Link the Windows addon with
/DELAYLOAD:node.exe and delayimp.
- Link a delay-load notification hook that resolves
node.exe to:
- an already loaded
libnode.dll, when present; otherwise
GetModuleHandleW(nullptr), the current process executable.
- Fail the build if PE validation finds
node.exe in the normal import directory or cannot find it in the delay-import directory.
- Add both Node.js and renamed-host Electron smoke coverage on Windows.
A product-specific PE rewrite from node.exe to echoo.exe confirms the diagnosis and is usable as a temporary downstream workaround, but it is not a general upstream fix because it binds the addon to one executable name.
Summary
The published Windows x64 addon in
@arcships/light-ocr@0.3.0importsnode.exethrough the normal PE import directory instead of the delay-import directory.That works when the host executable is actually
node.exe, but it is not safe for renamed Node-API hosts such as Electron. In the affected Electron application the host executable iselectron.exein development andechoo.exein production. Because neither basename satisfies the normalnode.exeimport, Windows resolves anothernode.exefromPATH. The addon then calls N-API exports in that separately mapped, uninitialized Node image and terminates the Electron process with an execute access violation.The crash is independent of OCR image size, GPU vendor, WebGPU, and execution-provider selection. Explicit
execution.provider = "cpu"crashes in the same way because the failure occurs while loading the native addon, before ONNX Runtime session creation or recognition.Affected environment
@arcships/light-ocr:0.3.037.10.0, embedded Node.js 22electron.exein development,echoo.exewhen packagedReproduction
node.exesucceeds.OcrError, rejected promise, or application-level error marker is emitted.Evidence
ocr.engine_init.start; there is noocr.engine_init.success,ocr.engine_init.error, or recognition marker.EXCEPTION_ACCESS_VIOLATIONwith execute address0x0569e006and process exit code0xFFFF7003.light_ocr_node.nodeand bundledonnxruntime.dll;@archshipsdim-desktop\\runtime\\node\\node.exeloaded fromPATH.node.exein its normal import directory with the required N-API symbols.node.exeimport.node.exedelay-loaded and a host redirection hook makes the same Electron 37 CPU OCR smoke recognizeHELLO 123successfully.Root cause
Linking a Windows Node-API addon with
node.libis normal; the import library commonly recordsnode.exeas the provider of Node/N-API exports. The defect is that this addon leavesnode.exeas a normal import and does not link an effective Windows delay-load hook.Node-API provides ABI stability, but it does not by itself redirect a normal PE import to a differently named host executable. Electron-compatible Windows addons must delay-load
node.exeand redirect that request to the current host module, following the establishedwin_delay_load_hookpattern.Expected behavior
The same Windows
.nodeartifact should load under supported Node-API hosts without assuming that the host executable basename isnode.exe. Failure should reject with a structured error rather than loading an unrelated executable fromPATHor terminating the process.Proposed upstream fix
/DELAYLOAD:node.exeanddelayimp.node.exeto:libnode.dll, when present; otherwiseGetModuleHandleW(nullptr), the current process executable.node.exein the normal import directory or cannot find it in the delay-import directory.A product-specific PE rewrite from
node.exetoechoo.execonfirms the diagnosis and is usable as a temporary downstream workaround, but it is not a general upstream fix because it binds the addon to one executable name.