Skip to content

Fix ClassCastException when SCMSource is not GitHubSCMSource#140

Open
kovalevsky wants to merge 1 commit intojenkinsci:masterfrom
kovalevsky:fix/null-scm-source-classcast
Open

Fix ClassCastException when SCMSource is not GitHubSCMSource#140
kovalevsky wants to merge 1 commit intojenkinsci:masterfrom
kovalevsky:fix/null-scm-source-classcast

Conversation

@kovalevsky
Copy link

Problem

The getKey() method in IssueCommentTrigger, LabelAddedTrigger, and PullRequestReviewTrigger performs an unsafe cast of the result of SCMSource.SourceByItem.findSource() to GitHubSCMSource:

final GitHubSCMSource scmSource = (GitHubSCMSource) SCMSource.SourceByItem.findSource(project);

This throws a ClassCastException when the source is a NullSCMSource (or any other non-GitHub SCM source):

java.lang.ClassCastException: class jenkins.scm.impl.NullSCMSource cannot be cast to class org.jenkinsci.plugins.github_branch_source.GitHubSCMSource
    at IssueCommentTrigger.getKey(IssueCommentTrigger.java:65)
    at IssueCommentTrigger.stop(IssueCommentTrigger.java:58)
    at PipelineTriggersJobProperty.stopTriggers(PipelineTriggersJobProperty.java:106)
    at WorkflowJob.addProperty(WorkflowJob.java:199)
    at BranchProjectFactory.decorate(BranchProjectFactory.java:255)
    at MultiBranchProject$SCMEventListenerImpl.processHeadUpdate(MultiBranchProject.java:1685)

Impact

This happens during the stop()/start() cycle triggered by MultiBranchProject.processHeadUpdate() when a push event causes BranchProjectFactory.decorate() to call stopTriggers(). The exception in stop() prevents the trigger from being re-registered in start(), silently removing the job from the DescriptorImpl.jobs map. Subsequent webhook events (issue comments, labels, PR reviews) for that PR are then silently ignored because the key lookup returns an empty set.

This is particularly hard to diagnose because:

  • The webhook returns HTTP 200
  • No error is logged at the time the webhook is processed (the handleIssueComment method just silently returns when the jobs map has no entry for the key)
  • The ClassCastException happens earlier during the push event processing, not during the comment event

Fix

Added instanceof checks before casting in getKey(), returning null when the source is not a GitHubSCMSource. Callers in start() and stop() now guard against null keys. A warning is logged when a non-GitHub SCM source is encountered to help diagnose similar issues.

The same fix is applied to all three affected trigger classes:

  • IssueCommentTrigger
  • LabelAddedTrigger
  • PullRequestReviewTrigger

The getKey() method in IssueCommentTrigger, LabelAddedTrigger, and
PullRequestReviewTrigger performs an unsafe cast of the result of
SCMSource.SourceByItem.findSource() to GitHubSCMSource. This throws
a ClassCastException when the source is a NullSCMSource (or any other
non-GitHub SCM source).

This happens during the stop()/start() cycle triggered by
MultiBranchProject.processHeadUpdate() when a push event causes
BranchProjectFactory.decorate() to call stopTriggers(). The exception
in stop() prevents the trigger from being re-registered in start(),
silently removing the job from the DescriptorImpl.jobs map. Subsequent
webhook events for that PR are then silently ignored because the key
lookup returns an empty set.

The fix adds instanceof checks before casting in getKey(), returning
null when the source is not a GitHubSCMSource, and guards callers in
start() and stop() against null keys. A warning is logged to help
diagnose similar issues in the future.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant