diff --git a/gracedb/urls.py b/gracedb/urls.py
index 2c71cc045303582d9294927df9fbfa8157772beb..05649126763271184da2082d45e1324ab6deb7b5 100644
--- a/gracedb/urls.py
+++ b/gracedb/urls.py
@@ -25,7 +25,7 @@ urlpatterns = patterns('gracedb.views',
     url (r'^(?P<graceid>[GEHMT]\d+)/log/(?P<num>([\d]*|preview))$', 'logentry', name="logentry"),
     url (r'^(?P<graceid>[GEHMT]\d+)/embblog/(?P<num>([\d]*|preview))$', 'embblogentry', name="embblogentry"),
     url (r'^(?P<graceid>[GEHMT]\d+)/emobservation/(?P<num>([\d]*|preview))$', 'emobservation_entry', name="emobservation_entry"),
-    url (r'^(?P<graceid>[GEHMT]\d+)/log/(?P<num>\d+)/tag/(?P<tagname>.+)$', 'taglogentry', name="taglogentry"),
+    url (r'^(?P<graceid>[GEHMT]\d+)/log/(?P<num>\d+)/tag/(?P<tagname>.*)$', 'taglogentry', name="taglogentry"),
 
 # RDW Aug 2014
 #(r'^admin/', include(admin.site.urls)),
diff --git a/gracedb/views.py b/gracedb/views.py
index 0e56897683235791fa3f4513d8cb05b40c63f891..edfd0c2d10cb21f2f82340977582d7be9290bd86 100644
--- a/gracedb/views.py
+++ b/gracedb/views.py
@@ -717,64 +717,77 @@ def latest(request):
 
 @event_and_auth_required
 def taglogentry(request, event, num, tagname):
+    # Note: this code is intertwined with the javascript in
+    # gracedb/templates/gracedb/event_detail_script.js,
+    # specifically lines 461-575, as of 2017/02/28.
+
+    # Get relevant log entry
     eventlog = event.eventlog_set.filter(N=num)[0]
 
     if request.method == "POST":
-        try:
-            # Has this tag-eventlog relationship already been created? 
-            tag = eventlog.tag_set.filter(name=tagname)[0]
-            msg = "Log already has tag %s" % tagname
+        # Handle cases where a user leaves the tagname blank.
+        if not tagname:
+            return HttpResponseBadRequest("Must specify a tagname.")
+
+        # Check authorization - not allowed to touch 'lvem' tag on other
+        # users' entries. May want to restrict this more in the future.
+        if (is_external(request.user) and
+            tagname == settings.EXTERNAL_ACCESS_TAGNAME):
+            if request.user != eventlog.issuer:
+                msg = "You do not have permission to add or remove this tag."
+                return HttpResponseForbidden(msg)
+
+        # Check if tag is already applied to this log entry.
+        tag_matches = eventlog.tag_set.filter(name=tagname)
+        if tag_matches:
+            msg = "Log already has tag %s." % tagname
             return HttpResponse(msg, content_type="text")
-        except:
-            # Check authorization
-            if is_external(request.user) and tagname == settings.EXTERNAL_ACCESS_TAGNAME:
-                if request.user != eventlog.issuer:
-                    msg = "You do not have permission to add or remove this tag."
-                    return HttpResponseForbidden(msg)
 
-            # Look for the tag.  If it doesn't already exist, create it.
-            try:
-                tag = Tag.objects.filter(name=tagname)[0]
-            except:
-                displayName = request.POST['displayName']
-                tag = Tag(name=tagname, displayName=displayName)
-                tag.save()
+        # Check if tag already exists in the database. If not, create it.
+        db_tags = Tag.objects.filter(name=tagname)
+        if not db_tags:
+            displayName = request.POST['displayName']
+            tag = Tag(name=tagname, displayName=displayName)
+            tag.save()
+        else:
+            tag = db_tags[0]
 
-            # Now add the log message to this tag.
-            tag.eventlogs.add(eventlog)
+        # Now add the log message to this tag.
+        tag.eventlogs.add(eventlog)
 
-            # Create a log entry to document the tag creation.
-            msg = "Tagged message %s: %s " % (num, tagname)
-            logentry = EventLog(event=event,
-                               issuer=request.user,
-                               comment=msg)
-            try:
-                logentry.save()
-            except Exception as e:
-                msg = "Failed to save log entry documenting tag:  "
-                msg = msg + str(e) + '\n'
-                msg = "The tag itself, however, is saved."
-                return HttpResponse(msg, content_type="text")
-    elif request.method == "DELETE":
+        # Create a log entry to document the tag creation.
+        msg = "Tagged message %s: %s " % (num, tagname)
+        logentry = EventLog(event=event,
+                            issuer=request.user,
+                            comment=msg)
         try:
-            # Has this tag-eventlog relationship already been created? 
-            tag = eventlog.tag_set.filter(name=tagname)[0]
-            tag.eventlogs.remove(eventlog)
-        except:
-            msg = "Attempted to delete tag that doesn't exist."
-            return HttpResponseBadRequest(msg)
-
-        # Check authorization
-        if is_external(request.user) and tagname == settings.EXTERNAL_ACCESS_TAGNAME:
+            logentry.save()
+        except Exception as e:
+            msg = "Failed to save log entry documenting tag:  "
+            msg = msg + str(e) + '\n'
+            msg = "The tag itself, however, is saved."
+            return HttpResponse(msg, content_type="text")
+    elif request.method == "DELETE":
+        # STEP 1: Check authorization
+        if (is_external(request.user) and
+            tagname == settings.EXTERNAL_ACCESS_TAGNAME):
             if request.user != eventlog.issuer:
                 msg = "You do not have permission to add or remove this tag."
                 return HttpResponseForbidden(msg)
+        # Check if tag is applied to this log entry.
+        tags = eventlog.tag_set.filter(name=tagname)
+        if tags:
+            tag = tags[0]
+            tag.eventlogs.remove(eventlog)
+        else:
+            msg = "Attempted to delete tag that doesn't exist."
+            return HttpResponseBadRequest(msg)
 
         # Create a log entry to document the tag deletion.
         msg = "Removed tag %s for message %s. " % (tagname, num)
         logentry = EventLog(event=event,
-                           issuer=request.user,
-                           comment=msg)
+                            issuer=request.user,
+                            comment=msg)
         try:
             logentry.save()
         except Exception as e:
@@ -786,7 +799,7 @@ def taglogentry(request, event, num, tagname):
     else:
         return HttpResponseBadRequest
 
-    # Hopefully, this will only ever be called form inside a script.  Just in case...
+    # Hopefully, this will only ever be called from inside a script.  Just in case...
     if not request.is_ajax():
         return HttpResponseRedirect(reverse(view, args=[event.graceid()]))
 
diff --git a/templates/gracedb/event_detail_script.js b/templates/gracedb/event_detail_script.js
index 5bbaf0f5a53c43f1cc197285a240bc64dba06500..216375224e7b5b7e915503c983f32909db9cb502 100644
--- a/templates/gracedb/event_detail_script.js
+++ b/templates/gracedb/event_detail_script.js
@@ -465,23 +465,28 @@ require([
                 var actionBar = domConstruct.create("div", { "class": "dijitDialogPaneActionBar" }); 
                 var tbnode = domConstruct.create("div", { 
                         style: "margin: 0px auto 0px auto; text-align: center;" 
-                }, actionBar); 
+                }, actionBar);
+                var reload_page = false;
                 var tagButton = new Button({ 
                     label: "Ok", 
                     onClick: function(){ 
-                    tagResultDialog.hide(); 
+                    tagResultDialog.hide();
+                    if (reload_page) { location.reload(true); }
                 }}).placeAt(tbnode); 
                 request.del(tagUrl).then( 
                     function(text){ 
                         tagResultDialog.set("content", text); 
                         domConstruct.place(actionBar, tagResultDialog.containerNode); 
-                        tagResultDialog.show(); 
-                        location.reload(true); 
+                        tagResultDialog.show();
+                        reload_page = true;
                     }, 
-                    function(error){ 
-                        tagResultDialog.set("content", "Error: " + error); 
+                    function(error){
+                        var err_msg = error;
+                        if (error.response.text) { err_msg = error.response.text; }
+                        tagResultDialog.set("content", "Error: " + err_msg);
                         domConstruct.place(actionBar, tagResultDialog.containerNode); 
-                        tagResultDialog.show();  
+                        tagResultDialog.show();
+                        reload_page = false;
                     });
                 } 
         }
@@ -493,11 +498,13 @@ require([
                 var actionBar = domConstruct.create("div", { "class": "dijitDialogPaneActionBar" }); 
                 var tbnode = domConstruct.create("div", { 
                         style: "margin: 0px auto 0px auto; text-align: center;" 
-                }, actionBar); 
+                }, actionBar);
+                var reload_page = false;
                 var tagButton = new Button({ 
                     label: "Ok", 
                     onClick: function(){ 
                     tagResultDialog.hide();
+                    if (reload_page) { location.reload(true); }
                     }
                 }).placeAt(tbnode); 
 
@@ -548,12 +555,15 @@ require([
                             tagResultDialog.set("content", text);
                             domConstruct.place(actionBar, tagResultDialog.containerNode);
                             tagResultDialog.show();
-                            location.reload(true);
+                            reload_page = true;
                         },
                         function(error){
-                            tagResultDialog.set("content", "Error: " + error);
+                            var err_msg = error;
+                            if (error.response.text) { err_msg = error.response.text; }
+                            tagResultDialog.set("content", "Error: " + err_msg);
                             domConstruct.place(actionBar, tagResultDialog.containerNode);
-                            tagResultDialog.show(); 
+                            tagResultDialog.show();
+                            reload_page = false;
                         }
                    );
                    addTagDialog.hide();