{"record":{"id":"c241338fe3b38752","repo":"mihomo-party-org/clash-party","slug":"usegroups-must-be-used-within-an-groupsprovider","errorCode":null,"errorMessage":"useGroups must be used within an GroupsProvider","messagePattern":"useGroups must be used within an GroupsProvider","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/src/hooks/use-groups.tsx","lineNumber":49,"sourceCode":"      mutate()\n    }\n    window.electron.ipcRenderer.on('groupsUpdated', handler)\n    return (): void => {\n      window.electron.ipcRenderer.removeListener('groupsUpdated', handler)\n    }\n  }, [mutate])\n\n  return (\n    <GroupsContext.Provider value={{ groups, mutate, showHidden, setShowHidden }}>\n      {children}\n    </GroupsContext.Provider>\n  )\n}\n\nexport const useGroups = (): GroupsContextType => {\n  const context = useContext(GroupsContext)\n  if (context === undefined) {\n    throw new Error('useGroups must be used within an GroupsProvider')\n  }\n  return context\n}\n","sourceCodeStart":31,"sourceCodeEnd":53,"githubUrl":"https://github.com/mihomo-party-org/clash-party/blob/911e090537acdf7c50bee1c3aebecc2ef119a8b5/src/renderer/src/hooks/use-groups.tsx#L31-L53","documentation":"useGroups is a React context consumer hook for the Groups context. It throws when called outside of a GroupsProvider because the context value is undefined — the library intentionally fails fast instead of returning null and causing a confusing downstream crash. This is a standard React context safety pattern.","triggerScenarios":"Calling useGroups() in a component that is not rendered as a descendant of <GroupsProvider>, or calling it in a module/top-level scope before the provider tree exists, or rendering the consuming component in a separate React root that does not include the provider.","commonSituations":"A component is moved into a portal, dialog, or lazily-rendered subtree mounted outside the provider; test renders (e.g. renderHook / RTL render) that forget to wrap with GroupsProvider; hooking it into a utility function invoked outside React render.","solutions":["Wrap the consuming component tree with <GroupsProvider> at an ancestor level (e.g. in App.tsx).","In tests, wrap with <GroupsProvider> (or a mock provider) inside render/renderHook.","If the component legitimately renders outside the tree, use a React portal that stays inside the provider's DOM/react subtree.","Re-export a safe wrapper hook that returns null and let callers handle the undefined case if the provider is optional in your app."],"exampleFix":"// before\nexport default function GroupList() {\n  const { groups } = useGroups()\n  return <div>{groups.map(g => g.name)}</div>\n}\n// after\nexport default function App() {\n  return (\n    <GroupsProvider>\n      <GroupList />\n    </GroupsProvider>\n  )\n}","handlingStrategy":"validation","validationCode":"// In the component, guard before consuming:\nconst context = React.useContext(GroupsContext)\nif (context === undefined) {\n  // render fallback or return early instead of calling the throwing hook\n  return <GroupsUnavailable />\n}","typeGuard":"function hasGroupsContext(c: GroupsContextType | undefined): c is GroupsContextType {\n  return c !== undefined\n}","tryCatchPattern":null,"preventionTips":["Always render consumers inside <GroupsProvider> (verify with React DevTools component tree).","Create a shared test wrapper that includes all app providers and reuse it in every render/renderHook call.","Keep providers mounted unconditionally at the app root rather than deep in conditional layouts.","Never call context hooks from module scope or plain (non-component) functions."],"tags":["react","context","hooks"],"backgroundTag":"react-context-used-outside-provider","analyzedSha":"911e090537acdf7c50bee1c3aebecc2ef119a8b5","analyzedAt":"2026-08-30T13:00:49.174Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}