actualbudget/actual · error

Unitialised context method called: onBudgetAction

Error message

Unitialised context method called: onBudgetAction

What it means

TrackingBudgetContext is created with placeholder defaults: onBudgetAction is a stub function that throws when called. The error means a component called the context's onBudgetAction without a TrackingBudgetContext.Provider being mounted above it (or the provider received no real implementation), so the consumer fell back to the createContext defaults.

Source

Thrown at packages/desktop-client/src/components/budget/tracking/TrackingBudgetContext.tsx:16

import React, { createContext, useContext } from 'react';
import type { ReactNode } from 'react';

import * as monthUtils from '@actual-app/core/shared/months';

type TrackingBudgetContextDefinition = {
  summaryCollapsed: boolean;
  onBudgetAction: (month: string, action: string, arg?: unknown) => void;
  onToggleSummaryCollapse: () => void;
  currentMonth: string;
};

const TrackingBudgetContext = createContext<TrackingBudgetContextDefinition>({
  summaryCollapsed: false,
  onBudgetAction: () => {
    throw new Error('Unitialised context method called: onBudgetAction');
  },
  onToggleSummaryCollapse: () => {
    throw new Error(
      'Unitialised context method called: onToggleSummaryCollapse',
    );
  },
  currentMonth: 'unknown',
});

type TrackingBudgetProviderProps = Omit<
  TrackingBudgetContextDefinition,
  'currentMonth'
> & {
  children: ReactNode;
};
export function TrackingBudgetProvider({
  summaryCollapsed,
  onBudgetAction,

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Wrap the consuming component tree in TrackingBudgetContext.Provider passing a real onBudgetAction implementation.
  2. Ensure the component is rendered inside the tracking-budget layout where the provider lives (packages/desktop-client/src/components/budget/tracking/TrackingBudgetContext.tsx).
  3. In tests, wrap the component under test with the provider (or a mock with jest.fn()/vi.fn() as onBudgetAction).
  4. In the hook, add a dev-time guard that reports the context was consumed without its provider.

Example fix

// before
export function MyWidget() {
  const { onBudgetAction } = useTrackingBudget(); // throws when called

// after
export function MyWidget() {
  return (
    <TrackingBudgetContext.Provider value={{ summaryCollapsed: false, onBudgetAction: handleBudgetAction, onToggleSummaryCollapse: toggle, currentMonth: month }}>
      <WidgetInner />
    </TrackingBudgetContext.Provider>
  );
Defensive patterns

Strategy: try-catch

Validate before calling

// guard before calling:
const ctx = useContext(TrackingBudgetContext);
const isProviderMissing = ctx.onBudgetAction === TrackingBudgetContext._currentValue?.onBudgetAction; // or expose a hasProvider flag on the context value
if (!ctx || typeof ctx.onBudgetAction !== 'function') throw new Error('TrackingBudgetContext provider missing');

Type guard

function hasTrackingBudgetContext(ctx: TrackingBudgetContextDefinition | null): ctx is TrackingBudgetContextDefinition {
  return ctx != null && typeof ctx.onBudgetAction === 'function' && typeof ctx.onToggleSummaryCollapse === 'function';
}

Try / catch

try {
  onBudgetAction('budget-set-amount', payload);
} catch (err) {
  if (err instanceof Error && err.message.includes('Unitialised context method called')) {
    logger.warn('TrackingBudgetContext not provided; budget action skipped');
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling onBudgetAction(...) from useTrackingBudget (or useContext(TrackingBudgetContext)) in a component rendered outside of the TrackingBudgetContext.Provider that supplies the real handler, e.g. a budget widget rendered under the non-tracking (report/basic) budget layout.

Common situations: Moving a component that uses tracking-budget hooks into the envelope/budget-rollover layout which uses a different context; testing a component in isolation without wrapping it in the provider; a refactor that renamed or removed the Provider while consumers stayed.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/ad88a954a4aec6d0. Report an issue: GitHub.