diff --git a/src/applications/maniphest/controller/ManiphestTaskEditController.php b/src/applications/maniphest/controller/ManiphestTaskEditController.php
--- a/src/applications/maniphest/controller/ManiphestTaskEditController.php
+++ b/src/applications/maniphest/controller/ManiphestTaskEditController.php
@@ -81,7 +81,7 @@
             $default_projects = mpull($default_projects, 'getPHID');
 
             if ($default_projects) {
-              $task->setProjectPHIDs($default_projects);
+              $task->attachProjectPHIDs($default_projects);
             }
           }
         }
@@ -215,7 +215,7 @@
         $task->setPriority($request->getInt('priority'));
         $task->setOwnerPHID($owner_phid);
         $task->setCCPHIDs($request->getArr('cc'));
-        $task->setProjectPHIDs($request->getArr('projects'));
+        $task->attachProjectPHIDs($request->getArr('projects'));
       } else {
 
         if ($can_edit_priority) {
@@ -438,7 +438,7 @@
             ->executeOne();
           if ($template_task) {
             $task->setCCPHIDs($template_task->getCCPHIDs());
-            $task->setProjectPHIDs($template_task->getProjectPHIDs());
+            $task->attachProjectPHIDs($template_task->getProjectPHIDs());
             $task->setOwnerPHID($template_task->getOwnerPHID());
             $task->setPriority($template_task->getPriority());
             $task->setViewPolicy($template_task->getViewPolicy());
diff --git a/src/applications/maniphest/editor/ManiphestTransactionEditor.php b/src/applications/maniphest/editor/ManiphestTransactionEditor.php
--- a/src/applications/maniphest/editor/ManiphestTransactionEditor.php
+++ b/src/applications/maniphest/editor/ManiphestTransactionEditor.php
@@ -150,8 +150,9 @@
       case ManiphestTransaction::TYPE_CCS:
         return $object->setCCPHIDs($xaction->getNewValue());
       case ManiphestTransaction::TYPE_PROJECTS:
-        $object->setProjectPHIDs($xaction->getNewValue());
-        ManiphestTaskProject::updateTaskProjects($object);
+        ManiphestTaskProject::updateTaskProjects(
+          $object,
+          $xaction->getNewValue());
         return $object;
       case ManiphestTransaction::TYPE_SUBPRIORITY:
         $data = $xaction->getNewValue();
diff --git a/src/applications/maniphest/query/ManiphestTaskQuery.php b/src/applications/maniphest/query/ManiphestTaskQuery.php
--- a/src/applications/maniphest/query/ManiphestTaskQuery.php
+++ b/src/applications/maniphest/query/ManiphestTaskQuery.php
@@ -331,6 +331,27 @@
     return $tasks;
   }
 
+  protected function didFilterPage(array $tasks) {
+    // TODO: Eventually, we should make this optional and introduce a
+    // needProjectPHIDs() method, but for now there's a lot of code which
+    // assumes the data is always populated.
+
+    $edge_query = id(new PhabricatorEdgeQuery())
+      ->withSourcePHIDs(mpull($tasks, 'getPHID'))
+      ->withEdgeTypes(
+        array(
+          PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
+        ));
+    $edge_query->execute();
+
+    foreach ($tasks as $task) {
+      $phids = $edge_query->getDestinationPHIDs(array($task->getPHID()));
+      $task->attachProjectPHIDs($phids);
+    }
+
+    return $tasks;
+  }
+
   private function buildTaskIDsWhereClause(AphrontDatabaseConnection $conn) {
     if (!$this->taskIDs) {
       return null;
diff --git a/src/applications/maniphest/storage/ManiphestTask.php b/src/applications/maniphest/storage/ManiphestTask.php
--- a/src/applications/maniphest/storage/ManiphestTask.php
+++ b/src/applications/maniphest/storage/ManiphestTask.php
@@ -37,6 +37,7 @@
 
   private $groupByProjectPHID = self::ATTACHABLE;
   private $customFields = self::ATTACHABLE;
+  private $edgeProjectPHIDs = self::ATTACHABLE;
 
   public static function initializeNewTask(PhabricatorUser $actor) {
     $app = id(new PhabricatorApplicationQuery())
@@ -52,7 +53,8 @@
       ->setPriority(ManiphestTaskPriority::getDefaultPriority())
       ->setAuthorPHID($actor->getPHID())
       ->setViewPolicy($view_policy)
-      ->setEditPolicy($edit_policy);
+      ->setEditPolicy($edit_policy)
+      ->attachProjectPHIDs(array());
   }
 
   public function getConfiguration() {
@@ -90,13 +92,13 @@
     return array_values(nonempty($this->ccPHIDs, array()));
   }
 
-  public function setProjectPHIDs(array $phids) {
-    $this->projectPHIDs = array_values($phids);
-    return $this;
+  public function getProjectPHIDs() {
+    return $this->assertAttached($this->edgeProjectPHIDs);
   }
 
-  public function getProjectPHIDs() {
-    return array_values(nonempty($this->projectPHIDs, array()));
+  public function attachProjectPHIDs(array $phids) {
+    $this->edgeProjectPHIDs = $phids;
+    return $this;
   }
 
   public function setCCPHIDs(array $phids) {
diff --git a/src/applications/maniphest/storage/ManiphestTaskProject.php b/src/applications/maniphest/storage/ManiphestTaskProject.php
--- a/src/applications/maniphest/storage/ManiphestTaskProject.php
+++ b/src/applications/maniphest/storage/ManiphestTaskProject.php
@@ -19,13 +19,15 @@
     );
   }
 
-  public static function updateTaskProjects(ManiphestTask $task) {
+  public static function updateTaskProjects(
+    ManiphestTask $task,
+    array $new_phids) {
+
     $edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
 
     $old_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
       $task->getPHID(),
       $edge_type);
-    $new_phids = $task->getProjectPHIDs();
 
     $add_phids = array_diff($new_phids, $old_phids);
     $rem_phids = array_diff($old_phids, $new_phids);
@@ -34,7 +36,6 @@
       return;
     }
 
-
     $editor = new PhabricatorEdgeEditor();
     foreach ($add_phids as $phid) {
       $editor->addEdge($task->getPHID(), $edge_type, $phid);