diff --git a/scheduler.cron.inc b/scheduler.cron.inc
index 511e979..fa60f54 100644
--- a/scheduler.cron.inc
+++ b/scheduler.cron.inc
@@ -37,6 +37,13 @@ function _scheduler_publish() {
 
   $nodes = Node::loadMultiple($nids);
   foreach ($nodes as $nid => $node) {
+    // The above query and api calls can return nodes of types which are not
+    // enabled for this scheduler action. Do not process these.
+    if (!$node->type->entity->getThirdPartySetting('scheduler', $action . '_enable', FALSE)) {
+      // @todo Maybe add a logger message to say that the node has been skipped?
+      continue;
+    }
+
     // Check that other modules allow the action on this node.
     if (!_scheduler_allow($node, $action)) {
       continue;
@@ -46,6 +53,13 @@ function _scheduler_publish() {
     // @todo For D8 move the 'pre' call to here.
     // See https://www.drupal.org/node/2311273
 
+    // Ensure we have a valid date to avoid a cron crash if third-party modules
+    // have altered the node list or node data via the API calls above.
+    if (empty($node->publish_on->value)) {
+      // @todo Maybe add a logger message to say that the node has been skipped?
+      continue;
+    }
+
     // Update timestamps.
     $publish_on = $node->publish_on->value;
     $node->set('changed', $publish_on);
@@ -64,7 +78,7 @@ function _scheduler_publish() {
       ));
     }
     // Unset publish_on so the node will not get rescheduled by subsequent calls
-    // to $node->save(). Save the value for use when calling Rules.
+    // to $node->save().
     $node->publish_on->value = NULL;
 
     // Invoke scheduler API to allow modules to alter the node before it is
@@ -119,6 +133,13 @@ function _scheduler_unpublish() {
 
   $nodes = Node::loadMultiple($nids);
   foreach ($nodes as $nid => $node) {
+    // The above query and api calls can return nodes of types which are not
+    // enabled for this scheduler action. Do not process these.
+    if (!$node->type->entity->getThirdPartySetting('scheduler', $action . '_enable', FALSE)) {
+      // @todo Maybe add a logger message to say that the node has been skipped?
+      continue;
+    }
+
     // Check that other modules allow the action on this node.
     if (!_scheduler_allow($node, $action)) {
       continue;
@@ -136,6 +157,13 @@ function _scheduler_unpublish() {
     // @todo For D8, move the 'pre' call to here.
     // See https://www.drupal.org/node/2311273
 
+    // Ensure we have a valid date to avoid cron crash if third-party modules
+    // have altered the node list or node data via the API calls above.
+    if (empty($node->unpublish_on->value)) {
+      // @todo Maybe add a logger message to say that the node has been skipped?
+      continue;
+    }
+
     // Update timestamps.
     $old_change_date = $node->getChangedTime();
     $unpublish_on = $node->unpublish_on->value;
