{"record":{"id":"00ec2c39ab7e6e50","repo":"remix-run/remix","slug":"nodehmrruntimeunavailableerror-00ec2c","errorCode":null,"errorMessage":"nodeHmrRuntimeUnavailableError","messagePattern":"nodeHmrRuntimeUnavailableError","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/node-hmr/src/runtime.ts","lineNumber":39,"sourceCode":"  async function createBrowserHmrChannel() {\n    throwNodeHmrRuntimeUnavailable()\n  }\n\n/**\n * Notifies the `node-hmr` parent that this child process is ready to serve requests.\n *\n * Call this after the app server starts listening. After a restart, `node-hmr` waits for this\n * signal before publishing the browser `server:update` event, preventing clients from refreshing\n * against a server that is not ready yet.\n */\nexport const emitServerReady: NodeHmrRuntimeApi['emitServerReady'] = function emitServerReady() {\n  throwNodeHmrRuntimeUnavailable()\n}\n\nthrowNodeHmrRuntimeUnavailable()\n\nfunction throwNodeHmrRuntimeUnavailable(): never {\n  throw new Error(nodeHmrRuntimeUnavailableError)\n}\n","sourceCodeStart":21,"sourceCodeEnd":41,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/node-hmr/src/runtime.ts#L21-L41","documentation":"In the fallback runtime implementation (runtime.ts), throwNodeHmrRuntimeUnavailable throws Error('The node-hmr/runtime API is only available when running inside node-hmr') whenever createBrowserHmrChannel or emitServerReady is invoked outside a node-hmr-supervised process. Unlike the eager module-level throw, this runtime loads but every API call fails, telling you the host process lacks the node-hmr runtime global.","triggerScenarios":"Calling remixNodeHmrRuntime.createBrowserHmrChannel() or .emitServerReady() when getNodeHmrRuntime() returned undefined — i.e. any process not spawned/registered by node-hmr.","commonSituations":"Dev scripts bypassing the node-hmr CLI; unit tests exercising code that calls emitServerReady(); environments (CI) where the node-hmr supervisor global was never installed.","solutions":["Run the dev server through the node-hmr CLI so the runtime global exists","Wrap createBrowserHmrChannel/emitServerReady calls in feature checks against the runtime global and skip them when absent","Catch the error and degrade gracefully (skip browser HMR wiring / server-ready signaling)"],"exampleFix":"// before\nruntime.emitServerReady()\n\n// after\ntry {\n  runtime.emitServerReady()\n} catch {\n  // not running under node-hmr; nothing to signal\n}","handlingStrategy":"try-catch","validationCode":"if (globalThis.__nodeHmrRuntime !== undefined) {\n  runtime.createBrowserHmrChannel()\n  runtime.emitServerReady()\n}","typeGuard":"function hasNodeHmrRuntime(): boolean {\n  return typeof globalThis === 'object' && (globalThis as any).__nodeHmrRuntime !== undefined\n}","tryCatchPattern":"try {\n  runtime.emitServerReady()\n} catch (error) {\n  if (error instanceof Error && error.message.includes('only available when running inside node-hmr')) {\n    // not under node-hmr — skip\n  } else throw error\n}","preventionTips":["Check for the node-hmr runtime global before calling createBrowserHmrChannel/emitServerReady","Run dev processes under the node-hmr supervisor","Make server-ready signaling optional in scripts that also run standalone"],"tags":["node-hmr","runtime-unavailable","dev-server"],"backgroundTag":"hmr-runtime-unavailable","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}