{"record":{"id":"05613a355ac42867","repo":"BloopAI/vibe-kanban","slug":"selected-profile-key-not-found","errorCode":null,"errorMessage":"Selected profile key not found","messagePattern":"Selected profile key not found","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/web-core/src/shared/dialogs/settings/settings/McpSettingsSection.tsx","lineNumber":156,"sourceCode":"\n    try {\n      if (mcpServers.trim()) {\n        try {\n          const fullConfig = JSON.parse(mcpServers);\n          McpConfigStrategyGeneral.validateFullConfig(mcpConfig, fullConfig);\n          const mcpServersConfig =\n            McpConfigStrategyGeneral.extractServersForApi(\n              mcpConfig,\n              fullConfig\n            );\n\n          const selectedProfileKey = profiles\n            ? Object.keys(profiles).find(\n                (key) => profiles[key] === selectedProfile\n              )\n            : null;\n          if (!selectedProfileKey) {\n            throw new Error('Selected profile key not found');\n          }\n\n          if (!machineClient) {\n            throw new Error('Machine client is required');\n          }\n\n          await machineClient.saveMcpServers(\n            {\n              executor: selectedProfileKey as BaseCodingAgent,\n            },\n            { servers: mcpServersConfig }\n          );\n\n          setOriginalMcpServers(mcpServers);\n          setSuccess(true);\n          setTimeout(() => setSuccess(false), 3000);\n        } catch (mcpErr) {\n          if (mcpErr instanceof SyntaxError) {","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/packages/web-core/src/shared/dialogs/settings/settings/McpSettingsSection.tsx#L138-L174","documentation":"handleApplyMcpServers throws 'Selected profile key not found' when the profiles record contains no value reference-equal to the selectedProfile being saved. The key is required as the `executor` argument for machineClient.saveMcpServers. Same root cause as the load path: the selected ExecutorProfile object is not from the current profiles map.","triggerScenarios":"User clicks Save (SettingsSaveBar onSave) after profiles were reloaded/replaced (or is null) so Object.keys(profiles).find(key => profiles[key] === selectedProfile) returns undefined.","commonSituations":"User System config refetched in background while editing MCP JSON, replacing profile objects; selected executor removed from config before saving; saving immediately after page load before profiles finished hydrating.","solutions":["Reopen the settings page so selectedProfile rebinds to the current profiles map, then save again","Keep the selected executor's string key in component state and use it directly for saveMcpServers instead of reverse-looking-up by object identity","Check the executor still exists in config; restore/rename it in the config file if removed","Serialize the save behind a check that profiles is loaded and contains selectedProfile"],"exampleFix":"// before\nconst selectedProfileKey = Object.keys(profiles).find((key) => profiles[key] === selectedProfile);\n// after (store key when selecting)\nconst [selectedKey, setSelectedKey] = useState<string | null>(null);\n// use selectedKey directly: saveMcpServers({ executor: selectedKey as BaseCodingAgent }, ...)","handlingStrategy":"validation","validationCode":"// before saving:\nif (!profiles || !selectedProfileKey) {\n  setMcpError('Agent selection is stale — reselect the agent and save again.');\n  return;\n}\nawait machineClient.saveMcpServers({ executor: selectedProfileKey as BaseCodingAgent }, { servers: mcpServersConfig });","typeGuard":"function hasSelectedProfileKey(profiles: Record<string, ExecutorProfile> | null, key: string | null): key is string {\n  return !!key && !!profiles && key in profiles;\n}","tryCatchPattern":"try {\n  const key = findProfileKey(profiles, selectedProfile); // by reference\n  if (!key) { setMcpError('Selected agent no longer exists — reselect and retry.'); return; }\n  await machineClient.saveMcpServers({ executor: key as BaseCodingAgent }, { servers: mcpServersConfig });\n  setSuccess(true);\n} catch (err) {\n  setMcpError(err instanceof Error ? err.message : t('settings.mcp.errors.saveFailed'));\n}","preventionTips":["Persist the executor key (string) in state when the user picks an agent, and save with that key","Revalidate the key exists in profiles before enabling Save","Rebind selectedProfile whenever the profiles record changes","Block saving while profiles is null or still loading"],"tags":["react","state","reference-equality"],"backgroundTag":"stale-object-reference","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}