<Tally> is a mutation. It applies at once, goes to the source’s mutate, and undoes with Cmd/Ctrl + Z. See Mutations and undo for the model.
When cells are editable
A cell is editable when the source has themutate capability and the column does not set editable: false. A read-only source turns every editing affordance off, including paste, fill, clear, the new row and CSV import.
The default editors are a text input for text and numbers, a date input for dates, and a combobox for enums. See Custom renderers and editors to replace them.
Parsing
Every value goes through the column type’sparse. A currency column accepts $5k, a date column accepts 2026-01-15, and an enum column accepts a value or a label. An empty value becomes null. A value that does not parse is skipped, so the cell keeps its old value.
Validating in the source
The source is where a business rule rejects a change. Returnaccepted: false with one error per problem, and the grid reverts the mutation and drops it from history.
validate.ts
A source that throws is treated the same way, with the error message. CSV import shows the first error in the status banner. A rejected cell edit reverts the cell, and
setCells returns the result with its errors.
Validating on the server
tally-server and tally/laravel validate every mutation request before it touches the database: unknown columns, columns with editable: false, values whose kind does not match the column, and rows without a key. A database error rejects the mutation with Mutation failed. validateMutationRequest(body, schema) in tally-protocol runs the same checks in your own handler. See Protocol.
New rows
grid.newRow() builds a blank row with a random UUID under the schema’s key field. Pass newRow to useGrid or createGrid when the key is computed or the row needs default values.