jashkenas/backbone · error · Error

Cannot sort a set without a comparator

Error message

Cannot sort a set without a comparator

What it means

Backbone's Collection.sort() requires the collection to have a comparator, which defines the ordering of models. If this.comparator is falsy, Backbone deliberately throws this error instead of silently leaving the collection unsorted. The comparator can be a function or a string naming an attribute to sort by.

Source

Thrown at backbone.js:1045

    // Return models with matching attributes. Useful for simple cases of
    // `filter`.
    where: function(attrs, first) {
      return this[first ? 'find' : 'filter'](attrs);
    },

    // Return the first model with matching attributes. Useful for simple cases
    // of `find`.
    findWhere: function(attrs) {
      return this.where(attrs, true);
    },

    // Force the collection to re-sort itself. You don't need to call this under
    // normal circumstances, as the set will maintain sort order as each item
    // is added.
    sort: function(options) {
      var comparator = this.comparator;
      if (!comparator) throw new Error('Cannot sort a set without a comparator');
      options || (options = {});

      var length = comparator.length;
      if (_.isFunction(comparator)) comparator = comparator.bind(this);

      // Run sort based on type of `comparator`.
      if (length === 1 || _.isString(comparator)) {
        this.models = this.sortBy(comparator);
      } else {
        this.models.sort(comparator);
      }
      if (!options.silent) this.trigger('sort', this, options);
      return this;
    },

    // Pluck an attribute from each model in the collection.
    pluck: function(attr) {
      return this.map(attr + '');

View on GitHub (pinned to f229c75b19)

Solutions

  1. Define a comparator on the collection: 'comparator: "name"' (sort by attribute) or 'comparator: function(m){ return m.get("name"); }'.
  2. Pass a comparator at construction: new Backbone.Collection(models, {comparator: 'id'}).
  3. Use a string comparator naming a model attribute if a custom function isn't needed.
  4. Before sorting, guard: if (!collection.comparator) collection.comparator = 'name'; then call collection.sort().
  5. If ordering doesn't matter, remove the sort() call instead of sorting a comparator-less collection.

Example fix

// before
var c = new Backbone.Collection(models);
c.sort(); // throws: Cannot sort a set without a comparator

// after
var c = new Backbone.Collection(models, {comparator: 'name'});
c.sort(); // works
Defensive patterns

Strategy: validation

Validate before calling

function canSort(collection) {
  return typeof collection === 'object' && collection != null &&
    (typeof collection.comparator === 'function' || typeof collection.comparator === 'string');
}
if (!canSort(myCollection)) myCollection.comparator = 'name';
myCollection.sort();

Type guard

function hasComparator(c) {
  return c instanceof Backbone.Collection &&
    (typeof c.comparator === 'function' || typeof c.comparator === 'string');
}

Try / catch

try {
  collection.sort();
} catch (e) {
  if (e.message === 'Cannot sort a set without a comparator') {
    collection.comparator = 'name';
    collection.sort();
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling collection.sort() on a Collection instance whose constructor options, 'comparator' property, or set() call never defined a comparator; also triggered internally by add/fetch with {sort:true} options on a comparator-less collection.

Common situations: Defining a comparator on the wrong object (e.g., on a plain object instead of the Collection class or prototype); building collections dynamically without a comparator then calling sort(); upgrading Backbone and relying on a comparator set via attributes rather than as a class property; copying collection code and omitting the comparator.

Related errors


AI-assisted analysis of jashkenas/backbone@f229c75b19 (2026-08-28). Data as JSON: /api/errors/1e27622d34312c0a. Report an issue: GitHub.