{"record":{"id":"fe39740e1d099e87","repo":"decolua/9router","slug":"this-provider-requires-accountid-in-providerspe","errorCode":null,"errorMessage":"${this.provider} requires accountId in providerSpecificData","messagePattern":"(.+?) requires accountId in providerSpecificData","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"open-sse/executors/default.js","lineNumber":132,"sourceCode":"      return `${normalized}${path}`;\n    }\n    if (this.provider?.startsWith?.(\"anthropic-compatible-\")) {\n      const baseUrl = credentials?.providerSpecificData?.baseUrl || ANTHROPIC_COMPAT_BASE;\n      const normalized = baseUrl.replace(/\\/$/, \"\");\n      return `${normalized}/messages`;\n    }\n    // gemini-format: build :streamGenerateContent / :generateContent path\n    if (this.config.format === \"gemini\") {\n      return `${this.config.baseUrl}/${model}:${stream ? \"streamGenerateContent?alt=sse\" : \"generateContent\"}`;\n    }\n    // urlSuffix (e.g. ?beta=true) declared per-provider in registry\n    if (this.config.urlSuffix) {\n      return `${this.config.baseUrl}${this.config.urlSuffix}`;\n    }\n    const url = this.config.baseUrl;\n    if (url?.includes(\"{accountId}\")) {\n      const accountId = credentials?.providerSpecificData?.accountId;\n      if (!accountId) throw new Error(`${this.provider} requires accountId in providerSpecificData`);\n      return url.replace(\"{accountId}\", accountId);\n    }\n    return url;\n  }\n\n  // Fallback descriptor for providers without an explicit entry in AUTH_DESCRIPTORS.\n  resolveAuthDescriptor() {\n    if (this.provider?.startsWith?.(\"anthropic-compatible-\")) {\n      return { apiKey: { header: \"x-api-key\", scheme: \"raw\" }, oauth: { header: \"Authorization\", scheme: \"bearer\" }, anthropicVersion: true };\n    }\n    if (this.config?.format === \"claude\") {\n      return { ...XAPIKEY, anthropicVersion: true };\n    }\n    return BEARER;\n  }\n\n  buildHeaders(credentials, stream = true, url, model) {\n    const rt = credentials?.runtimeTransport;","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/open-sse/executors/default.js#L114-L150","documentation":"Top-level catch of the MITM request handler: any exception thrown while classifying/routing the request (body collection, host→tool resolution, isChatRequest, model extraction/mapping, or handler dispatch) returns HTTP 500 JSON with type \"mitm_error\". It is the last-resort wrapper around handler intercepts that themselves throw outside their own try/catch.","triggerScenarios":"collectBodyRaw throws mid-read, getToolForHost/isChatRequest/extractModel/getMappedModel throw on an unexpected request shape, or handlers[tool].intercept rethrows (e.g. model is null where a mapped model was required).","commonSituations":"Malformed or truncated request bodies from the IDE; a tool handler with an unguarded code path; unexpected URL/header format after a tool update; bugs introduced when adding a new handler.","solutions":["Read `Unhandled error: <msg>` in the MITM log to find the failing step.","Retry the request; if reproducible, capture the request with the dumper/file log (ENABLE_FILE_LOG) to inspect the payload.","Verify the client request path/headers match what the handler expects (tool updates can change request shapes).","Update 9Router if the IDE shipped a new request format the extractor doesn't parse.","As a workaround, exclude that tool's host from MITM interception so it passes through untouched."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// sanity-check the request before sending through the MITM\nif (!request.url || !request.headers.host) throw new Error('request missing url/host — MITM dispatcher will 500');","typeGuard":null,"tryCatchPattern":"const res = await sendViaMitm(request);\nif (res.status === 500) {\n  const body = await res.json();\n  if (body.error?.type === 'mitm_error') {\n    // dispatcher-level failure — match `Unhandled error: <msg>` in MITM logs\n    // and enable ENABLE_FILE_LOG to capture the offending payload\n  }\n}","preventionTips":["Enable ENABLE_FILE_LOG/request dumping to capture payloads that trigger unhandled errors.","Keep 9Router updated when IDE tools change request shapes (URL/headers/body).","Exclude hosts from MITM interception that repeatedly hit the unhandled-error path.","Add regression coverage for any new handler so dispatch bugs surface before release."],"tags":["mitm","unhandled-exception","internal-server-error"],"backgroundTag":"mitm-proxy-intercept-failure","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}