{"record":{"id":"cc57457acf8f9fc3","repo":"affaan-m/ECC","slug":"unknown-session-adapter-id","errorCode":null,"errorMessage":"Unknown session adapter: ${id}","messagePattern":"Unknown session adapter: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/session-adapters/registry.js","lineNumber":107,"sourceCode":"      context: nextContext\n    };\n  }\n\n  return {\n    target: value,\n    context: nextContext\n  };\n}\n\nfunction createAdapterRegistry(options = {}) {\n  const adapters = options.adapters || createDefaultAdapters(options);\n\n  return {\n    adapters,\n    getAdapter(id) {\n      const adapter = adapters.find(candidate => candidate.id === id);\n      if (!adapter) {\n        throw new Error(`Unknown session adapter: ${id}`);\n      }\n\n      return adapter;\n    },\n    listAdapters() {\n      return adapters.map(adapter => ({\n        id: adapter.id,\n        description: adapter.description || '',\n        targetTypes: Array.isArray(adapter.targetTypes) ? [...adapter.targetTypes] : []\n      }));\n    },\n    select(target, context = {}) {\n      const normalized = normalizeStructuredTarget(target, context);\n      const adapter = normalized.context.adapterId\n        ? this.getAdapter(normalized.context.adapterId)\n        : adapters.find(candidate => candidate.canOpen(normalized.target, normalized.context));\n      if (!adapter) {\n        throw new Error(`No session adapter matched target: ${target}`);","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/session-adapters/registry.js#L89-L125","documentation":"Thrown by registry.getAdapter(id) when no adapter in the registered `adapters` array has a matching `id`. getAdapter is called directly, and indirectly by select()/open() whenever a target carries an `adapterId` (on the object or in context) that cannot be resolved to a real adapter.","triggerScenarios":"Calling registry.getAdapter('foo'); passing `{ adapterId: 'tmux' }` (typo for 'dmux-tmux'); supplying options.adapters as a custom array that omits the default adapters; a target.type that maps via TARGET_TYPE_TO_ADAPTER_ID to an adapter not present in the registry.","commonSituations":"Typos in adapter id (e.g. 'claude_history' with underscore, 'codex' vs 'codex-worktree'); injecting a filtered/custom adapters list for testing that leaves out the one a target needs; version drift where an adapter was renamed.","solutions":["Use a valid adapter id: claude-history, dmux-tmux, codex-worktree, or opencode (call registry.listAdapters() to confirm).","If you passed options.adapters, either omit it to get createDefaultAdapters(), or include the adapter your target requires.","Fix the typo — ids are kebab-case and exact."],"exampleFix":"// before\nregistry.select({}, { adapterId: 'tmux' });\n// throws: Unknown session adapter: tmux\n\n// after\nregistry.select({}, { adapterId: 'dmux-tmux' });","handlingStrategy":"validation","validationCode":"function resolveAdapterId(registry, id) {\n  const valid = new Set(registry.listAdapters().map(a => a.id));\n  if (!valid.has(id)) {\n    throw new Error(`adapter '${id}' not in: ${[...valid].join(', ')}`);\n  }\n  return id;\n}","typeGuard":"function isKnownAdapterId(registry, id) {\n  return typeof id === 'string' && registry.listAdapters().some(a => a.id === id);\n}","tryCatchPattern":"try {\n  registry.getAdapter(id);\n} catch (err) {\n  if (/Unknown session adapter/.test(err.message)) {\n    id = registry.listAdapters()[0]?.id; // fallback\n  } else throw err;\n}","preventionTips":["Call listAdapters() once and cache the id set instead of hardcoding ids.","Avoid passing a custom options.adapters unless you include every adapter your targets need.","Treat adapter ids as an enum, not freeform strings."],"tags":["session-adapters","adapter-lookup","validation"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}