actualbudget/actual · error

Unhandled edit field name: ${String(name)}

Error message

Unhandled edit field name: ${String(name)}

What it means

EditFieldModal throws when the `name` prop of the field being edited doesn't match any of the field types its render switch knows how to draw (e.g. account, payee, notes, category, date, amount...). Each editable transaction field has a bespoke input branch; an unknown name means the modal was asked to edit a field it has no editor for.

Source

Thrown at packages/desktop-client/src/components/modals/EditFieldModal.tsx:262

        </>
      );
      break;

    case 'amount':
      label = t('Amount');
      editor = ({ close }) => (
        <Input
          onEnter={value => {
            onSelect(value);
            close();
          }}
          style={inputStyle}
        />
      );
      break;

    default:
      throw new Error(`Unhandled edit field name: ${String(name)}`);
  }

  return (
    <Modal
      name="edit-field"
      noAnimation={!isNarrowWidth}
      onClose={onClose}
      containerProps={{
        style: {
          height: isNarrowWidth
            ? 'calc(var(--visual-viewport-height) * 0.85)'
            : height,
          padding: '15px 10px',
          ...(width && { width }),
          backgroundColor: theme.menuAutoCompleteBackground,
        },
      }}
    >

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Add a render branch for the reported field name in EditFieldModal's switch.
  2. Correct the `name` passed when dispatching pushModal({ name: 'edit-field', ... }) to a supported field.
  3. For custom fields, use the dedicated custom-field edit flow instead of edit-field.
  4. Fall back to a generic text input or close the modal with a warning instead of throwing.

Example fix

// before
default:
  throw new Error(`Unhandled edit field name: ${String(name)}`);
// after
case 'cleared':
  input = <Switch checked={value} onChange={onClose} />;
  break;
default:
  console.warn('Unhandled edit field name:', name);
  input = null;
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_FIELDS = ['account', 'payee', 'notes', 'category', 'date', 'amount', 'cleared'] as const;
type Field = typeof SUPPORTED_FIELDS[number];
if (!SUPPORTED_FIELDS.includes(name as Field)) {
  console.warn('edit-field does not support:', name);
  return; // don't open the modal
}

Type guard

type EditableField = 'account' | 'payee' | 'notes' | 'category' | 'date' | 'amount' | 'cleared';
function isEditableField(name: string): name is EditableField {
  return ['account', 'payee', 'notes', 'category', 'date', 'amount', 'cleared'].includes(name);
}

Try / catch

try {
  renderField(name);
} catch (err) {
  if (String(err).includes('Unhandled edit field')) {
    return null; // render modal without input, or skip opening it
  }
  throw err;
}

Prevention

When it happens

Trigger: Dispatching an 'edit-field' modal with a `name` outside the supported set — e.g. a new transaction field added elsewhere (like a custom field or a renamed field) opened through edit-field without adding a render branch.

Common situations: Developers adding a new transaction field and wiring it to EditFieldModal without a case; plugins or custom code opening the modal with an arbitrary field name; typos in the field name string.

Related errors


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