{"record":{"id":"4b6ffa5d009bf2be","repo":"mihomo-party-org/clash-party","slug":"useconfig-must-be-used-within-provider","errorCode":null,"errorMessage":"useConfig must be used within Provider","messagePattern":"useConfig must be used within Provider","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/src/hooks/create-config-context.tsx","lineNumber":40,"sourceCode":"    const { data: config, mutate } = useSWR(swrKey, fetcher)\n\n    useEffect(() => {\n      const handler = (): void => {\n        mutate()\n      }\n      window.electron.ipcRenderer.on(ipcEvent, handler)\n      return () => {\n        window.electron.ipcRenderer.removeListener(ipcEvent, handler)\n      }\n    }, [mutate])\n\n    return <Context.Provider value={{ config, mutate }}>{children}</Context.Provider>\n  }\n\n  const useConfig = (): ConfigContextValue<T> => {\n    const context = useContext(Context)\n    if (!context) {\n      throw new Error(`useConfig must be used within Provider`)\n    }\n    return context\n  }\n\n  return { Provider, useConfig, Context }\n}\n\ninterface ActionOptions {\n  errorKey: string\n  updateTray?: boolean\n}\n\nexport function useConfigAction<T>(\n  mutate: KeyedMutator<T>,\n  action: () => Promise<void>,\n  options: ActionOptions\n): () => Promise<void> {\n  const { t } = useTranslation()","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/mihomo-party-org/clash-party/blob/911e090537acdf7c50bee1c3aebecc2ef119a8b5/src/renderer/src/hooks/create-config-context.tsx#L22-L58","documentation":"createConfigContext() is a factory that builds a typed React context plus a useConfig hook. The generated hook throws 'useConfig must be used within Provider' when useContext returns undefined — i.e. the calling component has no corresponding <Provider> above it in the tree. It is a React context-contract violation error.","triggerScenarios":"Calling useXxxConfig() (generated by createConfigContext) from a component rendered outside <Provider> for that context; importing the hook in a utility/module executed outside React rendering; two separate instances of the module (duplicate bundling) so hook and provider use different context instances.","commonSituations":"A shared component moved to a page/layout that forgot to wrap with the provider; tests rendering a component without the provider; monorepo/bundler duplicate-module issues where provider and consumer resolve different copies of the file.","solutions":["Wrap the consuming component (or the route/layout) with the Provider produced by the same createConfigContext call.","Check import paths so the hook and the Provider come from one module instance (avoid deep imports that duplicate the module).","In tests, mount the component inside the provider or mock the context.","If a default is acceptable, pass a default value to createContext instead of undefined."],"exampleFix":"// before\nexport default function Panel() {\n  const { config } = useSysproxyConfig() // throws outside provider\n// after\nexport default function App() {\n  return (\n    <SysproxyConfigProvider>\n      <Panel />\n    </SysproxyConfigProvider>\n  )\n}","handlingStrategy":"try-catch","validationCode":"// at app root, ensure provider mounts before routes render\nif (!document.querySelector('[data-config-provider]')) console.warn('Provider not mounted yet')","typeGuard":null,"tryCatchPattern":"// recommended: fail fast in dev, default in prod\nfunction useConfigSafe() {\n  try {\n    return useConfig()\n  } catch {\n    if (import.meta.env.DEV) throw new Error('useConfig must be used within Provider')\n    return { config: defaultConfig, mutate: () => {} }\n  }\n}","preventionTips":["Mount every config provider at the root entry before routing.","Render components in tests/Storybook with provider wrappers (decorators).","Check bundler config for module duplication that splits context instances.","Prefer typing hooks to return non-nullable values so misuse is caught by lint/tests."],"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"}