{"record":{"id":"904e5bc7e4c0222f","repo":"actualbudget/actual","slug":"unitialised-context-method-called-ontogglesummary","errorCode":null,"errorMessage":"Unitialised context method called: onToggleSummaryCollapse","messagePattern":"Unitialised context method called: onToggleSummaryCollapse","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/desktop-client/src/components/budget/envelope/EnvelopeBudgetContext.tsx","lineNumber":19,"sourceCode":"import React, { createContext, useContext } from 'react';\nimport type { ReactNode } from 'react';\n\nimport * as monthUtils from '@actual-app/core/shared/months';\n\ntype EnvelopeBudgetContextDefinition = {\n  summaryCollapsed: boolean;\n  onBudgetAction: (month: string, action: string, arg?: unknown) => void;\n  onToggleSummaryCollapse: () => void;\n  currentMonth: string;\n};\n\nconst EnvelopeBudgetContext = createContext<EnvelopeBudgetContextDefinition>({\n  summaryCollapsed: false,\n  onBudgetAction: () => {\n    throw new Error('Unitialised context method called: onBudgetAction');\n  },\n  onToggleSummaryCollapse: () => {\n    throw new Error(\n      'Unitialised context method called: onToggleSummaryCollapse',\n    );\n  },\n  currentMonth: 'unknown',\n});\n\ntype EnvelopeBudgetProviderProps = Omit<\n  EnvelopeBudgetContextDefinition,\n  'currentMonth'\n> & {\n  children: ReactNode;\n};\nexport function EnvelopeBudgetProvider({\n  summaryCollapsed,\n  onBudgetAction,\n  onToggleSummaryCollapse,\n  children,\n}: EnvelopeBudgetProviderProps) {","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/desktop-client/src/components/budget/envelope/EnvelopeBudgetContext.tsx#L1-L37","documentation":"The sibling stub in EnvelopeBudgetContext: onToggleSummaryCollapse throws when the default (provider-less) context value is used. The collapse toggle only works when the real provider has wired it to local state in the envelope budget component.","triggerScenarios":"Clicking a summary collapse toggle (or calling onToggleSummaryCollapse from a custom component) outside the EnvelopeBudgetContext.Provider tree, including isolated test renders.","commonSituations":"Standalone renders of the budget summary/notes components; tests without the provider wrapper; refactors relocating the toggle component above the provider.","solutions":["Render the toggle under EnvelopeBudgetContext.Provider so the real state-backed handler is used.","Mock the context in tests with a no-op onToggleSummaryCollapse and assert it gets called instead of relying on the throwing default.","Check currentMonth !== 'unknown' before wiring UI to the context, surfacing a clear 'not inside provider' warning instead of crashing on click."],"exampleFix":"// before\nconst { onToggleSummaryCollapse } = useContext(EnvelopeBudgetContext);\n\n// after (guard against stub context)\nconst ctx = useContext(EnvelopeBudgetContext);\nif (ctx.currentMonth === 'unknown') {\n  console.warn('EnvelopeBudgetContext provider missing');\n  return null;\n}","handlingStrategy":"try-catch","validationCode":"const ctx = useContext(EnvelopeBudgetContext);\nif (ctx.currentMonth === 'unknown') {\n  console.warn('onToggleSummaryCollapse called without EnvelopeBudgetContext.Provider');\n  return;\n}","typeGuard":"function isInitializedEnvelopeContext(ctx: EnvelopeBudgetContextDefinition): ctx is EnvelopeBudgetContextDefinition & { currentMonth: string } {\n  return ctx.currentMonth !== 'unknown';\n}","tryCatchPattern":"try {\n  onToggleSummaryCollapse();\n} catch (e) {\n  if (String(e.message).includes('Unitialised context method')) {\n    setSummaryCollapsed(c => !c); // local fallback\n  } else throw e;\n}","preventionTips":["Keep the summary toggle component inside the provider subtree.","Mock the context in isolated renders to avoid the throwing stub.","Check the 'unknown' currentMonth sentinel before wiring click handlers to context methods."],"tags":["react","context","provider-missing","budget"],"backgroundTag":"context-used-outside-provider","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}