diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs
index eb4a57b1..a16cca77 100644
--- a/Core/FormBrowser.cs
+++ b/Core/FormBrowser.cs
@@ -552,19 +552,8 @@ public void ShowTweetDetail(string columnKey, string chirpId){
                 }
             }
 
-            browser.EvaluateScriptAsync("window.TDGF_showTweetDetail", columnKey, chirpId).ContinueWith(task => {
-                JavascriptResponse response = task.Result;
-                
-                if (response.Success){
-                    switch(response.Result as int? ?? -1){
-                        case 0: this.InvokeAsyncSafe(notification.FinishCurrentNotification); return;
-                        case 1: FormMessage.Error("View Tweet Detail", "The column which contained the tweet no longer exists.", FormMessage.OK); return;
-                        case 2: FormMessage.Error("View Tweet Detail", "The tweet has been unloaded.", FormMessage.OK); return; // TODO load the tweet 
-                    }
-                }
-
-                FormMessage.Error("View Tweet Detail", "An unknown error occurred when trying to view tweet detail.", FormMessage.OK);
-            });
+            notification.FinishCurrentNotification();
+            browser.ExecuteScriptAsync("window.TDGF_showTweetDetail", columnKey, chirpId);
         }
 
         public void OnTweetScreenshotReady(string html, int width, int height){
diff --git a/Core/Handling/ContextMenuNotification.cs b/Core/Handling/ContextMenuNotification.cs
index 1afdb0be..e9c42921 100644
--- a/Core/Handling/ContextMenuNotification.cs
+++ b/Core/Handling/ContextMenuNotification.cs
@@ -29,7 +29,10 @@ public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser br
             base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
 
             if (enableCustomMenu){
-                model.AddItem(MenuViewDetail, "View detail");
+                if (!string.IsNullOrEmpty(form.CurrentChirpId)){
+                    model.AddItem(MenuViewDetail, "View detail");
+                }
+
                 model.AddItem(MenuSkipTweet, "Skip tweet");
                 model.AddCheckItem(MenuFreeze, "Freeze");
                 model.SetChecked(MenuFreeze, form.FreezeTimer);
@@ -69,7 +72,7 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b
                     return true;
 
                 case MenuViewDetail:
-                    form.InvokeSafe(() => form.ShowTweetDetail());
+                    form.InvokeSafe(form.ShowTweetDetail);
                     return true;
 
                 case MenuCopyTweetUrl:
diff --git a/Core/Notification/FormNotificationBase.cs b/Core/Notification/FormNotificationBase.cs
index f181472a..af0f7498 100644
--- a/Core/Notification/FormNotificationBase.cs
+++ b/Core/Notification/FormNotificationBase.cs
@@ -82,6 +82,7 @@ public bool CanResizeWindow{
         private TweetNotification currentNotification;
         private int pauseCounter;
         
+        public string CurrentChirpId => currentNotification?.ChirpId;
         public string CurrentTweetUrl => currentNotification?.TweetUrl;
         public string CurrentQuoteUrl => currentNotification?.QuoteUrl;
         public bool IsPaused => pauseCounter > 0;
diff --git a/Resources/Scripts/code.js b/Resources/Scripts/code.js
index d35304a5..e0b75d12 100644
--- a/Resources/Scripts/code.js
+++ b/Resources/Scripts/code.js
@@ -196,10 +196,12 @@
         
         let source = tweet.getRelatedTweet();
         let duration = source ? source.text.length+(source.quotedTweet ? source.quotedTweet.text.length : 0) : tweet.text.length;
+        
+        let chirpId = source ? source.id : "";
         let tweetUrl = source ? source.getChirpURL() : "";
         let quoteUrl = source && source.quotedTweet ? source.quotedTweet.getChirpURL() : "";
 
-        $TD.onTweetPopup(column.model.privateState.key, tweet.id, columnTypes[column.getColumnType()] || "", html.html(), duration, tweetUrl, quoteUrl);
+        $TD.onTweetPopup(column.model.privateState.key, chirpId, columnTypes[column.getColumnType()] || "", html.html(), duration, tweetUrl, quoteUrl);
       }
 
       if (column.model.getHasSound()){
@@ -211,19 +213,36 @@
   //
   // Function: Shows tweet detail, used in notification context menu.
   //
-  window.TDGF_showTweetDetail = function(columnKey, tweetId){
-    let column = TD.controller.columnManager.get(columnKey);
-    return 1 if !column; // column no longer exists
+  (function(){
+    var showTweetDetailInternal = function(column, chirp){
+      TD.ui.updates.showDetailView(column, chirp, column.findChirp(chirp) || chirp);
+      TD.controller.columnManager.showColumn(column.model.privateState.key);
+
+      $(document).trigger("uiGridClearSelection");
+    };
     
-    let chirp = column.findMostInterestingChirp(tweetId);
-    return 2 if !chirp; // TODO figure out -- tweet is no longer in cache
-    
-    TD.ui.updates.showDetailView(column, chirp, column.findChirp(chirp));
-    TD.controller.columnManager.showColumn(columnKey);
-    
-    $(document).trigger("uiGridClearSelection");
-    return 0;
-  };
+    window.TDGF_showTweetDetail = function(columnKey, chirpId){
+      let column = TD.controller.columnManager.get(columnKey);
+      
+      if (!column){
+        $TD.alert("error", "The column which contained the tweet no longer exists.");
+        return;
+      }
+      
+      let chirp = column.findMostInterestingChirp(chirpId);
+      
+      if (chirp){
+        showTweetDetailInternal(column, chirp);
+      }
+      else{
+        TD.controller.clients.getPreferredClient().show(chirpId, function(chirp){
+          showTweetDetailInternal(column, chirp);
+        }, function(){
+          $TD.alert("error", "Could not retrieve the requested tweet.");
+        });
+      }
+    };
+  })();
   
   //
   // Function: Retrieves the tags to be put into <head> for notification HTML code.