{"record":{"id":"1a2a3cec344c1f9a","repo":"decolua/9router","slug":"tunnel-kill-warn-e-message","errorCode":null,"errorMessage":"[Tunnel] kill warn: ${e.message}","messagePattern":"\\[Tunnel\\] kill warn: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/lib/tunnel/cloudflare/manager.js","lineNumber":119,"sourceCode":"    return { success: true, tunnelUrl, shortId, publicUrl };\n  } catch (e) {\n    // Suppress noise when spawn was deliberately killed (restart/disable superseded it)\n    if (!/cloudflared killed|tunnel cancelled/.test(e.message)) {\n      console.error(`[Tunnel] enable error: ${e.message}`);\n    }\n    throw e;\n  } finally {\n    svc.spawnInProgress = false;\n  }\n}\n\nexport async function disableTunnel() {\n  console.log(\"[Tunnel] disable\");\n  // Abort any in-flight enable so it cannot resurrect state after we clear it\n  svc.cancelToken.cancelled = true;\n  setUnexpectedExitHandler(null);\n\n  try { killCloudflared(svc.activeLocalPort); } catch (e) { console.warn(`[Tunnel] kill warn: ${e.message}`); }\n  clearPid();\n\n  const state = loadState();\n  if (state) saveState({ shortId: state.shortId, tunnelUrl: null });\n\n  await updateSettings({ tunnelEnabled: false, tunnelUrl: \"\" });\n  // Force-clear flags so a subsequent enable is not blocked by a stuck spawnInProgress\n  svc.spawnInProgress = false;\n  svc.activeLocalPort = null;\n  return { success: true };\n}\n\nexport async function getTunnelStatus() {\n  const settings = await getSettings();\n  const settingsEnabled = settings.tunnelEnabled === true;\n  const state = loadState();\n  const shortId = state?.shortId || \"\";\n  const publicUrl = shortId ? `https://r${shortId}.abc-tunnel.us` : \"\";","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/lib/tunnel/cloudflare/manager.js#L101-L137","documentation":"disableTunnel tries to kill the active cloudflared process via killCloudflared(activeLocalPort). If that throws (process already gone, permission denied, missing pid info, signal error), it logs '[Tunnel] kill warn: <message>' and continues teardown: clears the pid file, clears state, and marks the tunnel disabled in settings. The kill failure alone does not fail the disable operation.","triggerScenarios":"killCloudflared throws while disabling: cloudflared already exited, pid file points at a dead/foreign PID (EPERM), the process is owned by another user, or the platform-specific kill command is unavailable.","commonSituations":"Double-disable races; cloudflared crashed earlier (so kill has nothing to kill); Docker/containers restricting signals; Windows process-permission issues; stale pid file after a reboot with PID reuse.","solutions":["Ignore if state shows tunnel disabled — disable succeeded and the process was likely already dead.","Check for orphaned cloudflared processes manually (ps aux | grep cloudflared) and kill them.","Clear the stale pid/state files in the data dir and re-run disableTunnel.","Fix permission context (run disable as the same user that spawned cloudflared)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check for a live cloudflared before/after disable\nimport { execSync } from \"child_process\";\nconst alive = (() => { try { return execSync(\"pgrep -f cloudflared\", { stdio: \"pipe\" }).toString().trim(); } catch { return \"\"; } })();","typeGuard":null,"tryCatchPattern":"// the library already swallows the kill error; mirror that in userland\ntry {\n  await disableTunnel();\n} catch (e) {\n  console.warn(\"disable failed:\", e.message);\n}","preventionTips":["Call disableTunnel only once; guard against double-click/race.","After unexpected cloudflared exits, clean up orphan processes before re-enabling.","Keep the pid/state files in a user-writable data dir.","Run enable and disable under the same user account."],"tags":["tunnel","cloudflare","process-kill","pid","teardown"],"backgroundTag":"process-kill-failed","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}