--- scheduler.module	2013-07-27 18:42:28.000000000 +0100
+++ scheduler.module	2013-09-14 13:29:56.000000000 +0100
@@ -430,8 +430,8 @@ function scheduler_list() {
   $query->limit(50);
   $query->addJoin('LEFT ', 'node', 'n', 's.nid = n.nid');
   $query->addJoin('LEFT ', 'users', 'u', 'u.uid = n.uid');
-  $query->fields('s', array('publish_on', 'unpublish_on'));
-  $query->fields('n', array('nid', 'uid', 'status', 'title'));
+  $query->fields('s', array('nid', 'publish_on', 'unpublish_on'));
+  $query->fields('n', array('uid', 'status', 'title'));
   $query->addField('u', 'name');
 
   // If this function is being called from a user account page then only select the nodes owned by
@@ -449,7 +449,7 @@ function scheduler_list() {
 
   foreach ($result as $node) {
     $rows[] = array(
-      l($node->title, "node/$node->nid"),
+      $node->title ? l($node->title, "node/$node->nid") : t('No title for node @nid', array('@nid' => $node->nid)),
       theme('username', array('account' => $node)),
       ($node->publish_on ? format_date($node->publish_on) : '&nbsp;'),
       ($node->unpublish_on ? format_date($node->unpublish_on) : '&nbsp;'),
@@ -763,6 +763,10 @@ function _scheduler_publish() {
 
   foreach ($nids as $nid) {
     $n                 = node_load($nid);
+    // Check the validity of the node object.
+    if (!_scheduler_check_node($n, $nid, 'publish')) {
+      continue;
+    }
     $n->changed        = $n->publish_on;
     $old_creation_date = $n->created;
     if (variable_get('scheduler_publish_touch_' . $n->type, 0) == 1) {
@@ -839,6 +843,10 @@ function _scheduler_unpublish() {
     // If this node is to be unpublished, we can update the node and remove the
     // record since it cannot be republished.
     $n               = node_load($nid);
+    // Check the validity of the node object.
+    if (!_scheduler_check_node($n, $nid, 'unpublish')) {
+      continue;
+    }
     $old_change_date = $n->changed;
     $n->changed      = $n->unpublish_on;
 
@@ -875,6 +883,42 @@ function _scheduler_unpublish() {
 }
 
 /**
+ * Helper function to check for proper node_load().
+ *
+ * Prevent creating empty nodes or any other corruption if the node_load() for
+ * this nid fails for whatever reason. Even if the problem was not caused by
+ * Scheduler we do not want to increase the difficulties by processing 'bad'
+ * nodes in the already corrupt database.
+ *
+ * @param $node
+ *  The fully loaded node object.
+ * @param $nid
+ *  The node id used to load the node.
+ * @param $op
+ *  The action being attempted, either 'publish' or 'unpublish'.
+ * @param $delete
+ *  Whether to delete the scheduler row if the node is invalid.
+ *  Defaults to TRUE for this module, but allows other modules to call this 
+ *  function in their implementations of hook_scheduler_nid_list_alter().
+ *
+ * @return
+ *  Boolean indicating validity of node object.
+ */
+function _scheduler_check_node($node, $nid, $op, $delete = TRUE) {
+  if (!is_object($node) || !isset($node->type) || empty($node->type)) {
+    watchdog('scheduler', 'Failed loading node @nid during attempted @action.', array('@nid' => $nid, '@action' => $op), WATCHDOG_ERROR, l(t('view'), 'node/' . $nid, array('alias' => TRUE)));
+    if ($delete) {
+      // This node cannot be processed, so delete the row from the Scheduler table.
+      $row_to_delete = new stdClass();
+      $row_to_delete->nid = $nid;
+      scheduler_node_delete($row_to_delete);
+    }
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
  * Gather node IDs for all nodes that need to be $action'ed
  *
  * @param $action
