decolua/9router · error
Unhandled error: ${e.message}
Error message
Unhandled error: ${e.message} What it means
Top-level catch of the MITM server's request handler. After DNS interception, body reading and model mapping, a recognized tool dispatches to its handler's intercept(); any synchronous or awaited throw outside the per-handler catches lands here, logged 'Unhandled error: <message>' and answered with a 500 JSON { message, type: 'mitm_error' }.
Source
Thrown at src/mitm/server.js:339
}
const model = extractModel(req.url, bodyBuffer);
// Intentional passthrough: some models must never be re-routed (e.g. Antigravity
// tab-autocomplete) so latency-critical inline completion stays native. Silent — this
// is by design, not a leak, and fires per keystroke. See MODEL_NO_MAP in config.js.
if (model && (MODEL_NO_MAP[tool] || []).some((re) => re.test(model))) {
return passthrough(req, res, bodyBuffer);
}
const mappedModel = getMappedModel(tool, model);
if (!mappedModel) {
return passthrough(req, res, bodyBuffer);
}
return handlers[tool].intercept(req, res, bodyBuffer, mappedModel, passthrough);
} catch (e) {
err(`Unhandled error: ${e.message}`);
if (!res.headersSent) res.writeHead(500, { "Content-Type": "application/json" });
res.end(JSON.stringify({ error: { message: e.message, type: "mitm_error" } }));
}
});
// Kill only processes LISTENING on LOCAL_PORT (not outbound connections)
function killPort(port) {
try {
let pidList = [];
if (IS_WIN) {
const psCmd = `powershell -NonInteractive -WindowStyle Hidden -Command ` +
`"Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess"`;
const out = execSync(psCmd, { encoding: "utf-8", windowsHide: true }).trim();
if (!out) return;
pidList = out.split(/\r?\n/).map(s => s.trim()).filter(p => p && Number(p) !== process.pid && Number(p) > 4);
} else {
const out = execSync(`${LSOF_BIN} -nP -iTCP:${port} -sTCP:LISTEN -t`, { encoding: "utf-8", windowsHide: true }).trim();
if (!out) return;View on GitHub (pinned to 90b52e06ff)
Solutions
- Read the logged message to identify which stage threw (mapping vs dispatch vs handler).
- Add/fix the model mapping so resolution returns null (→ passthrough) instead of throwing.
- Verify the tool's handler module exists and exports { intercept }.
- If the tool should not be intercepted, ensure it falls through to passthrough rather than the handlers map.
Example fix
// before const mappedModel = modelMap[tool][reqModel]; // throws if table missing // after const mappedModel = modelMap[tool]?.[reqModel] ?? null; // null → passthrough
Defensive patterns
Strategy: validation
Validate before calling
// guard dispatch inputs before invoking the handler if (typeof handlers[tool]?.intercept !== 'function') return passthrough(req, res, bodyBuffer); const mappedModel = modelMap[tool]?.[requestedModel] ?? null; if (typeof mappedModel !== 'string') return passthrough(req, res, bodyBuffer);
Type guard
function hasIntercept(h) {
return h !== null && typeof h === 'object' && typeof h.intercept === 'function';
} Try / catch
try {
if (!hasIntercept(handlers[tool])) return passthrough(req, res, bodyBuffer);
return handlers[tool].intercept(req, res, bodyBuffer, mappedModel, passthrough);
} catch (e) {
err(`Unhandled error: ${e.message}`);
if (!res.headersSent) res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: { message: e.message, type: 'mitm_error' } }));
} Prevention
- Use optional chaining on model-map lookups so unknown models fall through to passthrough.
- Validate handler modules export { intercept } at startup, not per-request.
- Keep tools that should not be intercepted out of the handlers map.
- Log unhandled errors with the tool name and URL for faster triage.
When it happens
Trigger: Handler dispatch throws before the per-tool try/catch: unknown tool name lookup, bodyBuffer read failure, model-map resolution throwing, or a handler module that itself throws synchronously (e.g. missing export).
Common situations: A tool not in the handlers map but also failing the passthrough path; model mapping table missing an entry and the mapper throwing instead of returning null; partially built/edited custom handler exporting a broken intercept.
Related errors
- ${this.provider} requires accountId in providerSpecificData
- Machine ID is required for Cursor API
- http2 module not available
- HTTP/2 is required for Cursor AgentService (endpoint is h2-o
- Cursor AgentService endpoint is not configured
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/41e618c1164f64f6.
Report an issue: GitHub.