actualbudget/actual · error

InitialFocus expects a single valid React element as its chi

Error message

InitialFocus expects a single valid React element as its child.

What it means

InitialFocus is a React wrapper that clones its single child and attaches a ref so the element receives focus on mount. It uses Children.only, so it throws if children is not exactly one valid React element.

Source

Thrown at packages/component-library/src/InitialFocus.ts:60

            ref.current instanceof HTMLInputElement ||
            ref.current instanceof HTMLTextAreaElement
          ) {
            ref.current.setSelectionRange(0, 10000);
          }
        }
      }, 0);
    }
  }, []);

  if (typeof children === 'function') {
    return children(ref);
  }

  const child = Children.only(children);
  if (isValidElement(child)) {
    return cloneElement(child, { ref });
  }
  throw new Error(
    'InitialFocus expects a single valid React element as its child.',
  );
}

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Ensure InitialFocus has exactly one element child.
  2. Wrap multiple children in a single element and put InitialFocus around the element that should receive focus.
  3. Move conditional rendering outside so a valid element is always passed, or conditionally render InitialFocus itself.

Example fix

// before
<InitialFocus>{cond && <Input />}</InitialFocus>
// after
{cond && <InitialFocus><Input /></InitialFocus>}
Defensive patterns

Strategy: validation

Validate before calling

import { Children, isValidElement } from 'react';
const child = Children.only(children);
if (!isValidElement(child)) {
  throw new Error('InitialFocus requires exactly one valid element child');
}

Type guard

import { Children, isValidElement, type ReactElement } from 'react';
function isSingleElement(children: React.ReactNode): children is ReactElement {
  const child = Children.only(children);
  return isValidElement(child);
}

Try / catch

try {
  return <InitialFocus>{child}</InitialFocus>;
} catch (err) {
  console.error('InitialFocus misuse:', (err as Error).message);
  return child;
}

Prevention

When it happens

Trigger: Rendering <InitialFocus> with zero children, multiple children, a string, a fragment of multiple elements, or a conditional returning null/false.

Common situations: Adding a second input inside InitialFocus during refactoring; JSX like <InitialFocus>{condition && <Input/>}</InitialFocus> where condition is false; passing text content instead of an element.

Related errors


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