SonarSource/sonarqube · warning

onChange() call failed on listener %s for events %s

Error message

onChange() call failed on listener %s for events %s

What it means

broadcastChangeEventToListener wraps each individual listener.onIssueChanges() call in try/catch(Exception). If a listener throws a regular Exception, it is logged as a warning naming the listener class and the event, so one broken listener does not affect others.

Source

Thrown at server/sonar-webserver-api/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImpl.java:111

    branchQgChangeEvents.forEach(changeEvent -> broadcastChangeEventToListeners(changedIssues, changeEvent));
  }

  private static ImmutableSet<ChangedIssue> toChangedIssues(Collection<DefaultIssue> defaultIssues, boolean fromAlm) {
    return defaultIssues.stream()
      .map(defaultIssue -> new ChangedIssueImpl(defaultIssue, fromAlm))
      .collect(toImmutableSet());
  }

  private void broadcastChangeEventToListeners(Set<ChangedIssue> changedIssues, QGChangeEvent changeEvent) {
    listeners.forEach(listener -> broadcastChangeEventToListener(changedIssues, changeEvent, listener));
  }

  private static void broadcastChangeEventToListener(Set<ChangedIssue> changedIssues, QGChangeEvent changeEvent, QGChangeEventListener listener) {
    try {
      LOG.trace("calling onChange() on listener {} for events {}...", listener.getClass().getName(), changeEvent);
      listener.onIssueChanges(changeEvent, changedIssues);
    } catch (Exception e) {
      LOG.warn(format("onChange() call failed on listener %s for events %s", listener.getClass().getName(), changeEvent), e);
    }
  }

}

View on GitHub (pinned to 184c821202)

Solutions

  1. Identify the listener class named in the log message and inspect its stack trace.
  2. Fix the bug in the custom listener (or report it to the plugin maintainer).
  3. Disable/uninstall the failing listener plugin if it cannot be fixed.
  4. Verify downstream effects (e.g. notifications/webhooks) and re-run the affected computation if events were dropped.

Example fix

// inside a custom listener
// before
public void onIssueChanges(QGChangeEvent event, Set<ChangedIssue> issues) { db.sessions()... }
// after
public void onIssueChanges(QGChangeEvent event, Set<ChangedIssue> issues) {
  try (DbSession s = db.openSession(false)) { ... }
}
Defensive patterns

Strategy: try-catch

Try / catch

// in your custom listener implementation
@Override
public void onIssueChanges(QGChangeEvent e, Set<ChangedIssue> issues) {
  try { doWork(e, issues); }
  catch (Exception ex) { LOG.warn("onChange failed", ex); }
}

Prevention

When it happens

Trigger: Any registered QGChangeEventListener whose onIssueChanges() implementation throws (DB failure, NPE, REST call failure inside the listener) during broadcastOnAnyChange or branch broadcast.

Common situations: Third-party webhooks/notification listener plugins failing on malformed events; a listener hitting a database outage while processing quality-gate changes.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/79ca58bd21f5b9f1. Report an issue: GitHub.