{"record":{"id":"c2b31f1ea7253331","repo":"mihomo-party-org/clash-party","slug":"usecontroledmihomoconfig-must-be-used-within-a-con","errorCode":null,"errorMessage":"useControledMihomoConfig must be used within a ControledMihomoConfigProvider","messagePattern":"useControledMihomoConfig must be used within a ControledMihomoConfigProvider","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/src/hooks/use-controled-mihomo-config.tsx","lineNumber":56,"sourceCode":"    window.electron.ipcRenderer.on('controledMihomoConfigUpdated', handler)\n    return (): void => {\n      window.electron.ipcRenderer.removeListener('controledMihomoConfigUpdated', handler)\n    }\n  }, [mutateControledMihomoConfig])\n\n  return (\n    <ControledMihomoConfigContext.Provider\n      value={{ controledMihomoConfig, mutateControledMihomoConfig, patchControledMihomoConfig }}\n    >\n      {children}\n    </ControledMihomoConfigContext.Provider>\n  )\n}\n\nexport const useControledMihomoConfig = (): ControledMihomoConfigContextType => {\n  const context = useContext(ControledMihomoConfigContext)\n  if (context === undefined) {\n    throw new Error('useControledMihomoConfig must be used within a ControledMihomoConfigProvider')\n  }\n  return context\n}\n","sourceCodeStart":38,"sourceCodeEnd":60,"githubUrl":"https://github.com/mihomo-party-org/clash-party/blob/911e090537acdf7c50bee1c3aebecc2ef119a8b5/src/renderer/src/hooks/use-controled-mihomo-config.tsx#L38-L60","documentation":"useControledMihomoConfig reads ControledMihomoConfigContext and throws 'useControledMihomoConfig must be used within a ControledMihomoConfigProvider' when the context is undefined. This two-way binding config (mihomo runtime settings synced with backend) must be consumed beneath its provider; consuming elsewhere is treated as a programming error.","triggerScenarios":"A component calls useControledMihomoConfig() while rendered outside <ControledMihomoConfigProvider>; the provider is conditionally mounted (e.g. only on the settings page) while other routes consume the hook; tests or modals render the consumer without the provider.","commonSituations":"New UI (e.g. a proxy settings widget) added on a page that lacks the provider; provider placed after a Suspense boundary that delays it; duplicate module resolution splitting the context instance between provider and hook.","solutions":["Hoist <ControledMihomoConfigProvider> to the root/layout that wraps every consumer of the hook.","Verify provider and hook resolve to a single module instance in the bundle.","Wrap conditionally rendered consumers (modals, portals) inside the provider subtree or pass config down via props.","For tests, add the provider to the render wrapper."],"exampleFix":"// before\nfunction Widget() {\n  const { controledMihomoConfig } = useControledMihomoConfig()\n// after\n;<ControledMihomoConfigProvider>\n  <Widget />\n</ControledMihomoConfigProvider>","handlingStrategy":"try-catch","validationCode":"// ensure provider wraps consuming routes\n;<ControledMihomoConfigProvider>\n  <Routes />\n</ControledMihomoConfigProvider>","typeGuard":null,"tryCatchPattern":"let mihomoConfig\ntry {\n  mihomoConfig = useControledMihomoConfig()\n} catch {\n  mihomoConfig = { controledMihomoConfig: {}, setControledMihomoConfig: () => {} }\n}","preventionTips":["Mount ControledMihomoConfigProvider above every route that reads mihomo settings.","Do not conditionally unmount the provider while consumers are mounted.","Include the provider in test/Storybook render wrappers.","Keep provider and hook in one module to avoid duplicate-context pitfalls."],"tags":["react","context","hook-misuse"],"backgroundTag":"hook-used-outside-provider","analyzedSha":"911e090537acdf7c50bee1c3aebecc2ef119a8b5","analyzedAt":"2026-08-30T13:00:49.174Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}