diff --git a/.github/workflows/prod-release.yml b/.github/workflows/prod-release.yml
index 91eed80ab7c..650078d6c6c 100644
--- a/.github/workflows/prod-release.yml
+++ b/.github/workflows/prod-release.yml
@@ -45,7 +45,7 @@ jobs:
- uses: actions/setup-node@v4
with:
- node-version: '22'
+ node-version-file: package.json
registry-url: 'https://registry.npmjs.org'
- name: Yarn
diff --git a/documentation/ag-grid-docs/public/changelog/changelog.json b/documentation/ag-grid-docs/public/changelog/changelog.json
index b03acc4f3a9..bd70fa6a91a 100644
--- a/documentation/ag-grid-docs/public/changelog/changelog.json
+++ b/documentation/ag-grid-docs/public/changelog/changelog.json
@@ -1,4 +1,18 @@
[
+ {
+ "key": "AG-16618",
+ "issueType": "Bug",
+ "manualEntry": true,
+ "summary": "Placeholder for 35.0.1",
+ "versions": ["35.0.1"],
+ "status": "Done",
+ "resolution": "Done",
+ "features": null,
+ "moreInformation": null,
+ "deprecationNotes": null,
+ "breakingChangesNotes": null,
+ "documentationUrl": null
+ },
{
"key": "AG-16379",
"issueType": "Bug",
diff --git a/documentation/ag-grid-docs/public/changelog/releaseVersionNotes.json b/documentation/ag-grid-docs/public/changelog/releaseVersionNotes.json
index 6518fea9881..2b2f9c2cea1 100644
--- a/documentation/ag-grid-docs/public/changelog/releaseVersionNotes.json
+++ b/documentation/ag-grid-docs/public/changelog/releaseVersionNotes.json
@@ -1,4 +1,8 @@
[
+ {
+ "release version": "35.0.1",
+ "markdown": "/releases/35_0_1.md"
+ },
{
"release version": "35.0.0",
"markdown": "/releases/35_0_0.md"
diff --git a/documentation/ag-grid-docs/public/changelog/releases/35_0_1.md b/documentation/ag-grid-docs/public/changelog/releases/35_0_1.md
new file mode 100644
index 00000000000..c483cc86053
--- /dev/null
+++ b/documentation/ag-grid-docs/public/changelog/releases/35_0_1.md
@@ -0,0 +1,3 @@
+#### 22nd Januray 2026 - Grid v35.0.1 (Charts v13.0.1)
+
+See table below for changes included in this release.
diff --git a/documentation/ag-grid-docs/src/content/docs/formula-editor-component/_examples/formula-editor-component-validation/example.spec.ts b/documentation/ag-grid-docs/src/content/docs/formula-editor-component/_examples/formula-editor-component-validation/example.spec.ts
new file mode 100644
index 00000000000..70f89aa9d01
--- /dev/null
+++ b/documentation/ag-grid-docs/src/content/docs/formula-editor-component/_examples/formula-editor-component-validation/example.spec.ts
@@ -0,0 +1,10 @@
+import { ensureGridReady, test, waitForGridContent } from '@utils/grid/test-utils';
+
+test.agExample(import.meta, () => {
+ test.eachFramework('Example', async ({ page }) => {
+ // PLACEHOLDER - MINIMAL TEST TO ENSURE GRID LOADS WITHOUT ERRORS
+ await ensureGridReady(page);
+ await waitForGridContent(page);
+ // END PLACEHOLDER
+ });
+});
diff --git a/documentation/ag-grid-docs/src/content/docs/formula-editor-component/_examples/formula-editor-component-validation/index.html b/documentation/ag-grid-docs/src/content/docs/formula-editor-component/_examples/formula-editor-component-validation/index.html
new file mode 100644
index 00000000000..378fad58398
--- /dev/null
+++ b/documentation/ag-grid-docs/src/content/docs/formula-editor-component/_examples/formula-editor-component-validation/index.html
@@ -0,0 +1 @@
+
diff --git a/documentation/ag-grid-docs/src/content/docs/formula-editor-component/_examples/formula-editor-component-validation/main.ts b/documentation/ag-grid-docs/src/content/docs/formula-editor-component/_examples/formula-editor-component-validation/main.ts
new file mode 100644
index 00000000000..ded44e420cd
--- /dev/null
+++ b/documentation/ag-grid-docs/src/content/docs/formula-editor-component/_examples/formula-editor-component-validation/main.ts
@@ -0,0 +1,114 @@
+import type { ColDef, GetRowIdParams, GridApi, GridOptions, ValueFormatterParams } from 'ag-grid-community';
+import {
+ ClientSideRowModelModule,
+ ModuleRegistry,
+ NumberEditorModule,
+ TextEditorModule,
+ ValidationModule,
+ createGrid,
+} from 'ag-grid-community';
+import { CellSelectionModule, FormulaModule } from 'ag-grid-enterprise';
+
+ModuleRegistry.registerModules([
+ CellSelectionModule,
+ ClientSideRowModelModule,
+ FormulaModule,
+ NumberEditorModule,
+ TextEditorModule,
+ ValidationModule,
+]);
+
+let gridApi: GridApi;
+
+const valueFormatter = ({ value }: ValueFormatterParams) => {
+ if (typeof value === 'string' && value.startsWith('#')) {
+ return value;
+ }
+ const numericValue = Number(value);
+ return Number.isFinite(numericValue) ? `$ ${numericValue.toFixed(2)}` : String(value ?? '');
+};
+const getRowId = (params: GetRowIdParams) => String(params.data.id);
+
+const columnDefs: ColDef[] = [
+ { field: 'item' },
+ { field: 'price', valueFormatter: valueFormatter },
+ { field: 'qty' },
+ {
+ field: 'total',
+ allowFormula: true,
+ valueFormatter: valueFormatter,
+ cellEditorParams: {
+ validateFormulas: true,
+ },
+ },
+];
+
+const gridOptions: GridOptions = {
+ columnDefs,
+ getRowId,
+ cellSelection: {
+ handle: {
+ mode: 'fill',
+ },
+ },
+ defaultColDef: {
+ editable: true,
+ flex: 1,
+ },
+ rowData: [
+ {
+ id: 1,
+ item: 'Apples',
+ price: 1.2,
+ qty: 4,
+ total: '=REF(COLUMN("price"),ROW(1))*REF(COLUMN("qty"),ROW(1))',
+ },
+ {
+ id: 2,
+ item: 'Bananas',
+ price: 0.5,
+ qty: 6,
+ total: '=B2*',
+ },
+ {
+ id: 3,
+ item: 'Oranges',
+ price: 0.8,
+ qty: 3,
+ total: '=REF(COLUMN("price"),ROW(3))*REF(COLUMN("qty"),ROW(3))',
+ },
+ {
+ id: 4,
+ item: 'Pears',
+ price: 1.4,
+ qty: 2,
+ total: '=REF(COLUMN("price"),ROW(4))*REF(COLUMN("qty"),ROW(4))',
+ },
+ {
+ id: 5,
+ item: 'Grapes',
+ price: 2.1,
+ qty: 3,
+ total: '=BADFUNC(1)',
+ },
+ {
+ id: 6,
+ item: 'Plums',
+ price: 1.5,
+ qty: 2,
+ total: '=REF(COLUMN("price"),ROW(6))*REF(COLUMN("qty"),ROW(6))',
+ },
+ {
+ id: 7,
+ item: 'Strawberries',
+ price: 1.8,
+ qty: 4,
+ total: '=REF(COLUMN("price"),ROW(7))*REF(COLUMN("qty"),ROW(7))',
+ },
+ ],
+};
+
+document.addEventListener('DOMContentLoaded', () => {
+ const gridDiv = document.querySelector('#myGrid')!;
+ gridApi = createGrid(gridDiv, gridOptions);
+});
diff --git a/documentation/ag-grid-docs/src/content/docs/formula-editor-component/index.mdoc b/documentation/ag-grid-docs/src/content/docs/formula-editor-component/index.mdoc
index 3e4e95ba921..14b0d1728fe 100644
--- a/documentation/ag-grid-docs/src/content/docs/formula-editor-component/index.mdoc
+++ b/documentation/ag-grid-docs/src/content/docs/formula-editor-component/index.mdoc
@@ -19,3 +19,24 @@ Range highlights and range handle editing require `cellSelection` to be enabled.
Providing a `cellEditor` opts the column out of the Formula Cell Editor. Formulas still evaluate, but range highlighting, handles, and function autocomplete are disabled because a different editor is in use.
{% gridExampleRunner title="Formula Editor Disabled" name="formula-editor-component-disabled" exampleHeight=320 /%}
+
+## Validation
+
+Invalid formulas already surface via the formula engine: the cell displays the error and shows a tooltip based on the grid's formula error state. Because of this, the Formula Cell Editor does not validate on every change by default.
+
+To opt into validation while editing, set `validateFormulas: true` on the editor params. Validation will also run if you provide a custom [getValidationErrors](./cell-editing-validation/#overriding-validation) callback. For more details on validation behaviour and presentation, see [Cell Editing Validation](./cell-editing-validation/).
+
+```js
+const columnDefs = [
+ {
+ field: 'total',
+ allowFormula: true,
+ cellEditorParams: {
+ validateFormulas: true,
+ },
+ },
+];
+```
+
+{% gridExampleRunner title="Formula Editor Validation" name="formula-editor-component-validation" exampleHeight=320 /%}
+
diff --git a/documentation/ag-grid-docs/src/content/docs/formulas/index.mdoc b/documentation/ag-grid-docs/src/content/docs/formulas/index.mdoc
index 7db7c7576f6..1ca54631d77 100644
--- a/documentation/ag-grid-docs/src/content/docs/formulas/index.mdoc
+++ b/documentation/ag-grid-docs/src/content/docs/formulas/index.mdoc
@@ -384,4 +384,4 @@ When performing an [Excel Export](./excel-export), the grid will export the form
## Next Up
-Continue to the next section: [Formula Editor Component](./formula-editor-component/).
\ No newline at end of file
+Continue to the next section: [Formula Editor Component](./formula-editor-component/).
diff --git a/documentation/ag-grid-docs/src/content/versions/ag-grid-versions.json b/documentation/ag-grid-docs/src/content/versions/ag-grid-versions.json
index 8a3f84c6928..daed884603d 100644
--- a/documentation/ag-grid-docs/src/content/versions/ag-grid-versions.json
+++ b/documentation/ag-grid-docs/src/content/versions/ag-grid-versions.json
@@ -1,4 +1,8 @@
[
+ {
+ "version": "35.0.1",
+ "date": "22nd January 2026"
+ },
{
"version": "35.0.0",
"date": "10th December 2025",
diff --git a/packages/ag-grid-community/src/edit/cellEditors/iFormulaCellEditor.ts b/packages/ag-grid-community/src/edit/cellEditors/iFormulaCellEditor.ts
new file mode 100644
index 00000000000..806dca4f6b3
--- /dev/null
+++ b/packages/ag-grid-community/src/edit/cellEditors/iFormulaCellEditor.ts
@@ -0,0 +1,11 @@
+import type { ICellEditorParams } from '../../interfaces/iCellEditor';
+
+export interface IFormulaCellEditorParams
+ extends ICellEditorParams {
+ /**
+ * Set to `true` to validate formulas while editing.
+ * If a custom `getValidationErrors` is provided, internal validation will still run.
+ * @default false
+ */
+ validateFormulas?: boolean;
+}
diff --git a/packages/ag-grid-community/src/main.ts b/packages/ag-grid-community/src/main.ts
index 20ff7587af2..97a60252f9f 100644
--- a/packages/ag-grid-community/src/main.ts
+++ b/packages/ag-grid-community/src/main.ts
@@ -342,6 +342,7 @@ export type { DateCellEditor } from './edit/cellEditors/dateCellEditor';
export type { DateStringCellEditor } from './edit/cellEditors/dateStringCellEditor';
export { IDateCellEditorParams } from './edit/cellEditors/iDateCellEditor';
export { IDateStringCellEditorParams } from './edit/cellEditors/iDateStringCellEditor';
+export { IFormulaCellEditorParams } from './edit/cellEditors/iFormulaCellEditor';
export { ILargeTextEditorParams } from './edit/cellEditors/iLargeTextCellEditor';
export { INumberCellEditorParams } from './edit/cellEditors/iNumberCellEditor';
export { ISelectCellEditorParams } from './edit/cellEditors/iSelectCellEditor';
diff --git a/packages/ag-grid-enterprise/src/formula/editor/formulaCellEditor.ts b/packages/ag-grid-enterprise/src/formula/editor/formulaCellEditor.ts
index ffa1b9fd56c..9a6f69f00eb 100644
--- a/packages/ag-grid-enterprise/src/formula/editor/formulaCellEditor.ts
+++ b/packages/ag-grid-enterprise/src/formula/editor/formulaCellEditor.ts
@@ -1,9 +1,9 @@
-import type { ICellEditorParams } from 'ag-grid-community';
import { AgAbstractCellEditor, KeyCode, RefPlaceholder, _isBrowserSafari, _placeCaretAtEnd } from 'ag-grid-community';
+import type { IFormulaCellEditorParams } from 'ag-grid-community';
import { AgFormulaInputField } from '../../widgets/agFormulaInputField';
-export class FormulaCellEditor extends AgAbstractCellEditor {
+export class FormulaCellEditor extends AgAbstractCellEditor {
protected eEditor: AgFormulaInputField = RefPlaceholder;
private focusAfterAttached = false;
@@ -11,7 +11,7 @@ export class FormulaCellEditor extends AgAbstractCellEditor {
super({ tag: 'div', cls: 'ag-cell-edit-wrapper' });
}
- public initialiseEditor(params: ICellEditorParams): void {
+ public initialiseEditor(params: IFormulaCellEditorParams): void {
const formulaInputField = this.createManagedBean(new AgFormulaInputField());
this.eEditor = formulaInputField;
@@ -75,7 +75,7 @@ export class FormulaCellEditor extends AgAbstractCellEditor {
event.stopPropagation();
}
- private getStartValue(params: ICellEditorParams): string | null | undefined {
+ private getStartValue(params: IFormulaCellEditorParams): string | null | undefined {
const { value } = params;
return value?.toString() ?? value;
}
@@ -125,11 +125,12 @@ export class FormulaCellEditor extends AgAbstractCellEditor {
const { params } = this;
const value = this.eEditor.getCurrentValue();
const translate = this.getLocaleTextFunc();
- const { getValidationErrors } = params;
+ const { getValidationErrors, validateFormulas } = params;
let internalErrors: string[] | null = null;
+ const shouldValidate = validateFormulas === true || !!getValidationErrors;
- if (typeof value === 'string' && this.isFormulaText(value)) {
+ if (shouldValidate && typeof value === 'string' && this.isFormulaText(value)) {
const normalised = this.beans.formula?.normaliseFormula(value, true);
if (!normalised) {