{"record":{"id":"daf62287c112f052","repo":"angular/components","slug":"selectionset-not-multiple-selection","errorCode":null,"errorMessage":"SelectionSet: not multiple selection","messagePattern":"SelectionSet: not multiple selection","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cdk-experimental/selection/selection-set.ts","lineNumber":62,"sourceCode":" * on them. Because `trackByFn` requires the index of the item to be passed in, the `index` field is\n * expected to be set when calling `isSelected`, `select` and `deselect`.\n */\nexport class SelectionSet<T> implements TrackBySelection<T> {\n  private _selectionMap = new Map<T | ReturnType<TrackByFunction<T>>, SelectableWithIndex<T>>();\n  changed = new Subject<SelectionChange<T>>();\n\n  constructor(\n    private _multiple = false,\n    private _trackByFn?: TrackByFunction<T>,\n  ) {}\n\n  isSelected(value: SelectableWithIndex<T>): boolean {\n    return this._selectionMap.has(this._getTrackedByValue(value));\n  }\n\n  select(...selects: SelectableWithIndex<T>[]) {\n    if (!this._multiple && selects.length > 1 && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw Error('SelectionSet: not multiple selection');\n    }\n\n    const before = this._getCurrentSelection();\n\n    if (!this._multiple) {\n      this._selectionMap.clear();\n    }\n\n    const toSelect: SelectableWithIndex<T>[] = [];\n    for (const select of selects) {\n      if (this.isSelected(select)) {\n        continue;\n      }\n\n      toSelect.push(select);\n      this._markSelected(this._getTrackedByValue(select), select);\n    }\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk-experimental/selection/selection-set.ts#L44-L80","documentation":"SelectionSet.select() throws this dev-mode assertion when more than one item is passed to select() while the SelectionSet was created in single-selection mode (multiple: false). The API guard exists so callers do not silently get a partially-applied multi-select on a set that only tracks one selection. It only fires in development builds (ngDevMode).","triggerScenarios":"Calling selectionSet.select(itemA, itemB) (spread of an array, or literal multiple args) on a SelectionSet constructed without multiple: true. Deselect/isSelected with one arg is fine; only select with >1 args on a non-multiple set throws.","commonSituations":"Refactoring code that used SelectionModel multiple mode to SelectionSet; passing a user-selected array straight into select(...items) while forgetting the `multiple` constructor option; a shared helper that always spreads arrays.","solutions":["Construct the SelectionSet with { multiple: true } if multi-select is intended.","Otherwise select items one at a time in a loop (each select() call replaces the previous selection in single mode).","Guard the call: only call select when the set is multiple, or slice to a single item."],"exampleFix":"// before\nconst set = new SelectionSet<string>(); // single mode\nset.select(...values);\n\n// after\nconst set = new SelectionSet<string>({ multiple: true });\nset.select(...values);","handlingStrategy":"validation","validationCode":"function canSelect(set: SelectionSet<unknown>, items: unknown[]): boolean {\n  return set.multiple || items.length <= 1;\n}\nif (!canSelect(set, values)) throw new Error('Cannot multi-select on a single SelectionSet');\nset.select(...values.slice(0, set.multiple ? values.length : 1));","typeGuard":"function isMultipleSet<T>(s: SelectionSet<T>): s is SelectionSet<T> & { multiple: true } {\n  return (s as { multiple?: boolean }).multiple === true;\n}","tryCatchPattern":"try {\n  set.select(...values);\n} catch (e) {\n  if ((e as Error).message.includes('not multiple selection')) {\n    values.forEach(v => set.select(v)); // degrade to sequential\n  } else throw e;\n}","preventionTips":["Always pass { multiple: true } when any call site may pass more than one item.","Type helpers to accept a single SelectableWithIndex unless the set is multiple.","Run dev builds in CI — ngDevMode assertions surface this early."],"tags":["angular","cdk","selection","dev-mode-assertion"],"backgroundTag":"single-selection-mode-multiple-values","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}