slint-ui/slint · error · TypeError

insertRow is not implemented on this model

Error message

insertRow is not implemented on this model

What it means

This is the same not-implemented sentinel as removeRow, thrown by the base Model class when insertRow has not been overridden. It also surfaces indirectly: pushRow's default implementation calls insertRow, so calling pushRow on a subclass that implements neither method lands here. It means the model is effectively read-only unless the subclass adds the insertion hook.

Solutions

  1. Override insertRow(index, data), mutate storage, then call rowInserted(index).
  2. Use ArrayModel/ReadOnlyModel's pushRow instead of a bare custom Model.
  3. Switch the property binding to an ArrayModel backed by your array.

Example fix

// before
class M extends slint.Model { rowCount() { return this.items.length; } }
// after
class M extends slint.Model {
  insertRow(index, data) { this.items.splice(index, 0, data); this.rowInserted(index); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

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

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling insertRow(index, data) directly, or pushRow(data), on a Model subclass that does not implement insertRow.

Common situations: Growing a custom model from JS or .slint (button pushes rows) while the subclass was written read-only.

Related errors


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

Appendix: source

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

     * 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);
    }

    /**
     * Notifies the view that the data of the current row is changed.
     * @param row index of the changed row.
     */
    protected notifyRowDataChanged(row: number): void {
        napi.jsModelNotifyRowDataChanged(this.modelNotify, row);
    }

    /**
     * Notifies the view that multiple rows are added to the model.
     * @param row index of the first added row.
     * @param count the number of added items.

View on GitHub (pinned to bb937076de)