slint-ui/slint · error · TypeError

removeRow is not implemented on this model

Error message

removeRow is not implemented on this model

What it means

BaseModel.removeRow is an abstract extension point: the base class provides no removal behavior and deliberately throws a TypeError whenever a model subclass has not overridden removeRow. It fires when application code calls removeRow (directly or via helpers) on a custom Model that only implemented the read-only parts of the interface. It is not a runtime data error — it is the default implementation's sentinel telling the developer their model class must supply the mutation.

Solutions

  1. Override removeRow(index) in the subclass, call rowRemoved(index) after mutating backing storage.
  2. Use ReadOnlyModel or ArrayModel which implement removeRow.
  3. Keep the model read-only and remove delete actions from the UI.

Example fix

// before
class M extends slint.Model { rowCount() { return this.items.length; } }
// after
class M extends slint.Model {
  removeRow(index) { this.items.splice(index, 1); this.rowRemoved(index); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (model.removeRow === slint.Model.prototype.removeRow) throw new Error('model cannot remove rows');

Type guard

function supportsRemoveRow<T>(m: slint.Model<T>): boolean {
  return m.removeRow !== slint.Model.prototype.removeRow;
}

Try / catch

try {
  model.removeRow(index);
} catch (e) {
  if (e instanceof TypeError && /removeRow is not implemented/.test(e.message)) {
    console.warn('row removal unsupported by this model');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling removeRow(index) on a Model subclass that does not override removeRow, or .slint code invoking model.remove-row on such a model.

Common situations: Implementing a minimal read-only Model and later wiring UI delete buttons to it; forgetting the override when the model became editable.

Related errors


AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16). Data as JSON: /api/errors/cbe79c5be5578b80. Report an issue: GitHub.

Appendix: source

Thrown at api/node/typescript/models.ts:154

    /**
     * Adds a line to the model with the provided data.
     * Throws when the model rejects the modification.
     * The default implementation calls {@link Model.insertRow} with the row count.
     * @param data new data item to store in a new row.
     */
    pushRow(data: T): void {
        this.insertRow(this.rowCount(), data);
    }

    /**
     * Implementations of this function must remove the row at the specified index.
     * Throws when the model rejects the modification; the default implementation
     * always throws.
     * @param _index index of the row to remove.
     */
    removeRow(_index: number): void {
        throw new TypeError("removeRow is not implemented on this model");
    }

    /**
     * Implementations of this function must add a row at the specified index, pushing all next
     * rows to the right.
     * Throws when the model rejects the modification; the default implementation
     * always throws.
     * @param _index index of the row to insert.
     * @param _data new data item to store in a new row.
     */
    insertRow(_index: number, _data: T): void {
        throw new TypeError("insertRow is not implemented on this model");
    }

    [Symbol.iterator](): Iterator<T> {
        return new ModelIterator(this);
    }

View on GitHub (pinned to bb937076de)