angular/angular.js · error · Error

No rAF callbacks present

Error message

No rAF callbacks present

What it means

ngMock decorates $$rAF with a queue and a flush() that runs all queued requestAnimationFrame callbacks (then re-slices the queue in case callbacks cancelled or queued more). Flushing an empty queue means nothing scheduled a frame, so it throws 'No rAF callbacks present' — same 'nothing to flush' contract as the other mock flushes.

Source

Thrown at src/ngMock/angular-mocks.js:2405

  return $delegate;
}];

angular.mock.$RAFDecorator = ['$delegate', function($delegate) {
  var rafFn = function(fn) {
    var index = rafFn.queue.length;
    rafFn.queue.push(fn);
    return function() {
      rafFn.queue.splice(index, 1);
    };
  };

  rafFn.queue = [];
  rafFn.supported = $delegate.supported;

  rafFn.flush = function() {
    if (rafFn.queue.length === 0) {
      throw new Error('No rAF callbacks present');
    }

    var length = rafFn.queue.length;
    for (var i = 0; i < length; i++) {
      rafFn.queue[i]();
    }

    rafFn.queue = rafFn.queue.slice(i);
  };

  return rafFn;
}];

/**
 *
 */
var originalRootElement;
angular.mock.$RootElementProvider = function() {

View on GitHub (pinned to d8f77817eb)

Solutions

  1. Guard the flush: only call $$rAF.flush() when $$rAF.queue.length > 0.
  2. Trigger the code that schedules the rAF callback before flushing.
  3. Drop the manual $$rAF.flush() if $animate.flush() already ran — it flushes the rAF queue as part of its loop.

Example fix

// before
$animate.flush();
$$rAF.flush(); // throws: queue already drained above

// after
$animate.flush();
if ($$rAF.queue.length) {
  $$rAF.flush();
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard the rAF flush by queue length
inject(function($$rAF) {
  if ($$rAF.queue.length > 0) {
    $$rAF.flush();
  }
});

Prevention

When it happens

Trigger: Calling $$rAF.flush() with no rAF callbacks registered: the code path that calls $$rAF(fn) (often via $animate or a rAF-based directive) never ran; a previous $animate.flush() already drained the $$rAF queue and then the test flushes it again.

Common situations: Manually flushing $$rAF in animation tests while $animate.flush() also drains it internally, so the second flush finds an empty queue; rAF scheduling hidden behind a condition (element attached, class change) that the test did not satisfy.

Related errors


AI-assisted analysis of angular/angular.js@d8f77817eb (2026-08-21). Data as JSON: /api/errors/f0646e63f2dc0880. Report an issue: GitHub.