mihomo-party-org/clash-party · error · Error
useControledMihomoConfig must be used within a ControledMiho
Error message
useControledMihomoConfig must be used within a ControledMihomoConfigProvider
What it means
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.
Source
Thrown at src/renderer/src/hooks/use-controled-mihomo-config.tsx:56
window.electron.ipcRenderer.on('controledMihomoConfigUpdated', handler)
return (): void => {
window.electron.ipcRenderer.removeListener('controledMihomoConfigUpdated', handler)
}
}, [mutateControledMihomoConfig])
return (
<ControledMihomoConfigContext.Provider
value={{ controledMihomoConfig, mutateControledMihomoConfig, patchControledMihomoConfig }}
>
{children}
</ControledMihomoConfigContext.Provider>
)
}
export const useControledMihomoConfig = (): ControledMihomoConfigContextType => {
const context = useContext(ControledMihomoConfigContext)
if (context === undefined) {
throw new Error('useControledMihomoConfig must be used within a ControledMihomoConfigProvider')
}
return context
}
View on GitHub (pinned to 911e090537)
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.
Example fix
// before
function Widget() {
const { controledMihomoConfig } = useControledMihomoConfig()
// after
;<ControledMihomoConfigProvider>
<Widget />
</ControledMihomoConfigProvider> Defensive patterns
Strategy: try-catch
Validate before calling
// ensure provider wraps consuming routes ;<ControledMihomoConfigProvider> <Routes /> </ControledMihomoConfigProvider>
Try / catch
let mihomoConfig
try {
mihomoConfig = useControledMihomoConfig()
} catch {
mihomoConfig = { controledMihomoConfig: {}, setControledMihomoConfig: () => {} }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- useConfig must be used within Provider
- useAppConfig must be used within an AppConfigProvider
- Missing profile import handler
- Missing profile update handler
- useGroups must be used within an GroupsProvider
AI-assisted analysis of mihomo-party-org/clash-party@911e090537 (2026-08-30).
Data as JSON: /api/errors/c2b31f1ea7253331.
Report an issue: GitHub.