Fix a bug in which --experimental_post_build_query crashes if asked to run on a graph without edges. Now we fail gracefully.
PiperOrigin-RevId: 175294923
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
index ef26627..7290852 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
@@ -124,19 +124,20 @@
    *
    * <p>The caller is responsible for setting up and syncing the package cache.
    *
-   * <p>During this function's execution, the actualTargets and successfulTargets
-   * fields of the request object are set.
+   * <p>During this function's execution, the actualTargets and successfulTargets fields of the
+   * request object are set.
    *
    * @param request the build request that this build tool is servicing, which specifies various
-   *        options; during this method's execution, the actualTargets and successfulTargets fields
-   *        of the request object are populated
+   *     options; during this method's execution, the actualTargets and successfulTargets fields of
+   *     the request object are populated
    * @param result the build result that is the mutable result of this build
    * @param validator target validator
    */
   public void buildTargets(BuildRequest request, BuildResult result, TargetValidator validator)
       throws BuildFailedException, InterruptedException, ViewCreationFailedException,
           TargetParsingException, LoadingFailedException, AbruptExitException,
-          InvalidConfigurationException, TestExecException {
+          InvalidConfigurationException, TestExecException,
+          ConfiguredTargetQueryCommandLineException {
     validateOptions(request);
     BuildOptions buildOptions = runtime.createBuildOptions(request);
     // Sync the package manager before sending the BuildStartingEvent in runLoadingPhase()
@@ -237,6 +238,10 @@
         // graph beforehand if this option is specified, or add another option to wipe if desired
         // (SkyframeExecutor#handleConfiguredTargetChange should be sufficient).
         if (request.getBuildOptions().queryExpression != null) {
+          if (!env.getSkyframeExecutor().hasIncrementalState()) {
+            throw new ConfiguredTargetQueryCommandLineException(
+                "Configured query is not allowed if incrementality state is not being kept");
+          }
           try {
             doConfiguredTargetQuery(request, configurations, loadingResult);
           } catch (QueryException | IOException e) {
@@ -373,6 +378,9 @@
     } catch (TargetParsingException | LoadingFailedException | ViewCreationFailedException e) {
       exitCode = ExitCode.PARSING_FAILURE;
       reportExceptionError(e);
+    } catch (ConfiguredTargetQueryCommandLineException e) {
+      exitCode = ExitCode.COMMAND_LINE_ERROR;
+      reportExceptionError(e);
     } catch (TestExecException e) {
       // ExitCode.SUCCESS means that build was successful. Real return code of program
       // is going to be calculated in TestCommand.doTest().
@@ -684,4 +692,10 @@
   private Reporter getReporter() {
     return env.getReporter();
   }
+
+  private static class ConfiguredTargetQueryCommandLineException extends Exception {
+    ConfiguredTargetQueryCommandLineException(String message) {
+      super(message);
+    }
+  }
 }
diff --git a/src/test/shell/integration/discard_graph_edges_test.sh b/src/test/shell/integration/discard_graph_edges_test.sh
index 7cc2d84..e6b2e4d 100755
--- a/src/test/shell/integration/discard_graph_edges_test.sh
+++ b/src/test/shell/integration/discard_graph_edges_test.sh
@@ -78,6 +78,14 @@
   expect_log "//testing:system_malloc"
 }
 
+function test_configured_query() {
+  bazel $STARTUP_FLAGS build $BUILD_FLAGS --nobuild \
+      --experimental_post_build_query='deps(//testing:mytest, 1)' \
+      //testing:mytest >& "$TEST_log" && fail "Expected failure"
+  exit_code="$?"
+  [[ "$exit_code" == 2 ]] || fail "Expected exit code 2 but was $exit_code"
+}
+
 function test_top_level_aspect() {
   mkdir -p "foo" || fail "Couldn't make directory"
   cat > foo/simpleaspect.bzl <<'EOF' || fail "Couldn't write bzl file"