diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java
index c53942a..8180dc4 100644
--- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionScorer.java
@@ -194,9 +194,9 @@ abstract class DisjunctionScorer extends Scorer {
   protected abstract float score(DisiWrapper topList) throws IOException;
 
   @Override
-  public final Collection<ChildScorer> getChildren() {
+  public final Collection<ChildScorer> getChildren() throws IOException {
     ArrayList<ChildScorer> children = new ArrayList<>();
-    for (DisiWrapper scorer : subScorers) {
+    for (DisiWrapper scorer = getSubMatches(); scorer != null; scorer = scorer.next) {
       children.add(new ChildScorer(scorer.scorer, "SHOULD"));
     }
     return children;
diff --git a/lucene/core/src/java/org/apache/lucene/search/MinShouldMatchSumScorer.java b/lucene/core/src/java/org/apache/lucene/search/MinShouldMatchSumScorer.java
index 032b5fe..8328d49 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MinShouldMatchSumScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MinShouldMatchSumScorer.java
@@ -20,7 +20,6 @@ package org.apache.lucene.search;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
 import org.apache.lucene.util.PriorityQueue;
@@ -94,7 +93,6 @@ final class MinShouldMatchSumScorer extends Scorer {
   final DisiWrapper[] tail;
   int tailSize;
 
-  final Collection<ChildScorer> childScorers;
   final long cost;
 
   MinShouldMatchSumScorer(Weight weight, Collection<Scorer> scorers, int minShouldMatch) {
@@ -119,17 +117,17 @@ final class MinShouldMatchSumScorer extends Scorer {
       addLead(new DisiWrapper(scorer));
     }
 
-    List<ChildScorer> children = new ArrayList<>();
-    for (Scorer scorer : scorers) {
-      children.add(new ChildScorer(scorer, "SHOULD"));
-    }
-    this.childScorers = Collections.unmodifiableCollection(children);
     this.cost = cost(scorers, minShouldMatch);
   }
 
   @Override
-  public final Collection<ChildScorer> getChildren() {
-    return childScorers;
+  public final Collection<ChildScorer> getChildren() throws IOException {
+    List<ChildScorer> matchingScorers = new ArrayList<>();
+    updateFreq();
+    for (DisiWrapper s = lead; s != null; s = s.next) {
+      matchingScorers.add(new ChildScorer(s.scorer, "SHOULD"));
+    }
+    return matchingScorers;
   }
 
   @Override
diff --git a/lucene/core/src/java/org/apache/lucene/search/Scorer.java b/lucene/core/src/java/org/apache/lucene/search/Scorer.java
index f434327..7ceed33 100644
--- a/lucene/core/src/java/org/apache/lucene/search/Scorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/Scorer.java
@@ -77,9 +77,15 @@ public abstract class Scorer {
     return weight;
   }
   
-  /** Returns child sub-scorers
-   * @lucene.experimental */
-  public Collection<ChildScorer> getChildren() {
+  /**
+   * Returns child sub-scorers positioned on the current document
+   *
+   * Note that this method should not be called on Scorers passed to {@link LeafCollector#setScorer(Scorer)},
+   * as these may be synthetic Scorers produced by {@link BulkScorer} which will throw an Exception.
+   *
+   * @lucene.experimental
+   */
+  public Collection<ChildScorer> getChildren() throws IOException {
     return Collections.emptyList();
   }
   
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java b/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java
index 60ba528..60b6c26 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java
@@ -169,7 +169,7 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
       };
     }
     
-    private void fillLeaves(Scorer scorer, Set<Scorer> set) {
+    private void fillLeaves(Scorer scorer, Set<Scorer> set) throws IOException {
       if (scorer.getWeight().getQuery() instanceof TermQuery) {
         set.add(scorer);
       } else {
@@ -186,7 +186,40 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
     public int freq(int doc) throws IOException {
       return docCounts.get(doc);
     }
-    
+
+  }
+
+  public void testDisjunctionMatches() throws IOException {
+    BooleanQuery.Builder bq1 = new BooleanQuery.Builder();
+    bq1.add(new TermQuery(new Term(F1, "lucene")), Occur.SHOULD);
+    bq1.add(new PhraseQuery(F2, "search", "engine"), Occur.SHOULD);
+
+    Weight w1 = scorerSearcher.createNormalizedWeight(bq1.build(), true);
+    Scorer s1 = w1.scorer(reader.leaves().get(0));
+    assertEquals(0, s1.iterator().nextDoc());
+    assertEquals(2, s1.getChildren().size());
+
+    BooleanQuery.Builder bq2 = new BooleanQuery.Builder();
+    bq2.add(new TermQuery(new Term(F1, "lucene")), Occur.SHOULD);
+    bq2.add(new PhraseQuery(F2, "search", "library"), Occur.SHOULD);
+
+    Weight w2 = scorerSearcher.createNormalizedWeight(bq2.build(), true);
+    Scorer s2 = w2.scorer(reader.leaves().get(0));
+    assertEquals(0, s2.iterator().nextDoc());
+    assertEquals(1, s2.getChildren().size());
+  }
+
+  public void testMinShouldMatchMatches() throws IOException {
+    BooleanQuery.Builder bq = new BooleanQuery.Builder();
+    bq.add(new TermQuery(new Term(F1, "lucene")), Occur.SHOULD);
+    bq.add(new TermQuery(new Term(F2, "lucene")), Occur.SHOULD);
+    bq.add(new PhraseQuery(F2, "search", "library"), Occur.SHOULD);
+    bq.setMinimumNumberShouldMatch(2);
+
+    Weight w = scorerSearcher.createNormalizedWeight(bq.build(), true);
+    Scorer s = w.scorer(reader.leaves().get(0));
+    assertEquals(0, s.iterator().nextDoc());
+    assertEquals(2, s.getChildren().size());
   }
 
   public void testGetChildrenMinShouldMatchSumScorer() throws IOException {
@@ -203,12 +236,12 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
     for (String summary : collector.getSummaries()) {
       assertEquals(
           "ConjunctionScorer\n" +
-          "    MUST ConstantScoreScorer\n" +
-          "    MUST MinShouldMatchSumScorer\n" +
-          "            SHOULD TermScorer body:nutch\n" +
-          "            SHOULD TermScorer body:web\n" +
-          "            SHOULD TermScorer body:crawler",
-          summary);
+              "    MUST ConstantScoreScorer\n" +
+              "    MUST MinShouldMatchSumScorer\n" +
+              "            SHOULD TermScorer body:crawler\n" +
+              "            SHOULD TermScorer body:web\n" +
+              "            SHOULD TermScorer body:nutch",
+              summary);
     }
   }
 
@@ -261,7 +294,7 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
       };
     }
 
-    private static void summarizeScorer(final StringBuilder builder, final Scorer scorer, final int indent) {
+    private static void summarizeScorer(final StringBuilder builder, final Scorer scorer, final int indent) throws IOException {
       builder.append(scorer.getClass().getSimpleName());
       if (scorer instanceof TermScorer) {
         TermQuery termQuery = (TermQuery) scorer.getWeight().getQuery();
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java b/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java
index 121e48d..7b713b9 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java
@@ -80,7 +80,7 @@ public class TestSubScorerFreqs extends LuceneTestCase {
       this.relationships = relationships;
     }
     
-    public void setSubScorers(Scorer scorer, String relationship) {
+    public void setSubScorers(Scorer scorer, String relationship) throws IOException {
       for (ChildScorer child : scorer.getChildren()) {
         if (scorer instanceof AssertingScorer || relationships.contains(child.relationship)) {
           setSubScorers(child.child, child.relationship);
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/AssertingSubDocsAtOnceCollector.java b/lucene/facet/src/test/org/apache/lucene/facet/AssertingSubDocsAtOnceCollector.java
index 793cc412..e545244 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/AssertingSubDocsAtOnceCollector.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/AssertingSubDocsAtOnceCollector.java
@@ -16,6 +16,7 @@
  */
 package org.apache.lucene.facet;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -32,7 +33,7 @@ class AssertingSubDocsAtOnceCollector extends SimpleCollector {
   List<Scorer> allScorers;
 
   @Override
-  public void setScorer(Scorer s) {
+  public void setScorer(Scorer s) throws IOException {
     // Gathers all scorers, including s and "under":
     allScorers = new ArrayList<>();
     allScorers.add(s);
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
index b581dd5..37990ea 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
@@ -502,7 +502,7 @@ public class LTRScoringQuery extends Query {
       }
 
       @Override
-      public Collection<ChildScorer> getChildren() {
+      public Collection<ChildScorer> getChildren() throws IOException {
         return featureTraversalScorer.getChildren();
       }
 
