angular/components · error · Error

Cannot begin editing a chip that is not editable.

Error message

Cannot begin editing a chip that is not editable.

What it means

MatChipRowHarness.startEditing() simulates a dblclick to put a chip row into editing mode, but this only works when the chip is configured as editable. The harness checks isEditable() first and throws if the chip is not editable, because the double-click would have no effect.

Source

Thrown at src/material/chips/testing/chip-row-harness.ts:31

/** Harness for interacting with a mat-chip-row in tests. */
export class MatChipRowHarness extends MatChipHarness {
  static override hostSelector = '.mat-mdc-chip-row';

  /** Whether the chip is editable. */
  async isEditable(): Promise<boolean> {
    return (await this.host()).hasClass('mat-mdc-chip-editable');
  }

  /** Whether the chip is currently being edited. */
  async isEditing(): Promise<boolean> {
    return (await this.host()).hasClass('mat-mdc-chip-editing');
  }

  /** Sets the chip row into an editing state, if it is editable. */
  async startEditing(): Promise<void> {
    if (!(await this.isEditable())) {
      throw new Error('Cannot begin editing a chip that is not editable.');
    }
    return (await this.host()).dispatchEvent('dblclick');
  }

  /** Stops editing the chip, if it was in the editing state. */
  async finishEditing(): Promise<void> {
    if (await this.isEditing()) {
      await (await this.host()).sendKeys(TestKey.ENTER);
    }
  }

  /** Gets the edit input inside the chip row. */
  async getEditInput(filter: ChipEditInputHarnessFilters = {}): Promise<MatChipEditInputHarness> {
    return this.locatorFor(MatChipEditInputHarness.with(filter))();
  }
}

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Set the editable input on the chip: <mat-chip-row editable ...>
  2. Verify with (await harness.isEditable()) before attempting to edit
  3. Ensure the harness targets a chip row (MatChipRowHarness) and not a static non-editable chip

Example fix

// before
<mat-chip-row>{{chip.name}}</mat-chip-row>
// after
<mat-chip-row editable (edited)="rename(chip, $event)">{{chip.name}}</mat-chip-row>
Defensive patterns

Strategy: validation

Validate before calling

if (!(await chipHarness.isEditable())) {
  throw new Error('Chip is not editable; set [editable] on the chip first.');
}
await chipHarness.startEditing();

Try / catch

try {
  await chipHarness.startEditing();
} catch (e) {
  if ((e as Error).message.includes('not editable')) {
    // adjust fixture/template to set editable, then retry
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling startEditing() on a chip rendered without the editable input set (e.g. <mat-chip-row> without [editable]="true").

Common situations: Testing chip editing flows where the mat-chip-set/grid was created without editable chips; forgetting to bind the editable input after copying test code; testing edit on display-only chips.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/58a7c4aaee3695b0. Report an issue: GitHub.