Index: tractags/macros.py
===================================================================
--- tractags/macros.py	(revision 14745)
+++ tractags/macros.py	(working copy)
@@ -14,7 +14,7 @@
 from pkg_resources import resource_filename
 
 from trac.config import BoolOption, ListOption, Option
-from trac.core import Component, implements
+from trac.core import Component, TracError, implements
 from trac.resource import Resource, get_resource_description, \
                           get_resource_url, render_resource_link
 from trac.ticket.api import TicketSystem
@@ -356,7 +356,7 @@
                 # Tag count is too low.
                 continue
             if ul:
-                # Found new tag for cloud; now add previously prepared one. 
+                # Found new tag for cloud; now add previously prepared one.
                 ul('\n', li)
             else:
                 # Found first tag for cloud; now create the list.
@@ -371,11 +371,16 @@
 
     def _paginate(self, req, results, realms):
         query = req.args.get('q', None)
-        current_page = as_int(req.args.get('listtagged_page'), 1)
+        current_page = max(as_int(req.args.get('listtagged_page'), 1), 1)
         items_per_page = as_int(req.args.get('listtagged_per_page'), None)
-        if items_per_page is None:
+        if items_per_page is None or items_per_page < 1:
             items_per_page = self.items_per_page
-        result = Paginator(results, current_page - 1, items_per_page)
+        try:
+            result = Paginator(results, current_page - 1, items_per_page)
+        except (AssertionError, TracError), e:
+            self.log.warn("ListTagged macro: %s", e)
+            current_page = 1
+            result = Paginator(results, current_page - 1, items_per_page)
 
         pagedata = []
         shown_pages = result.get_shown_pages(21)
Index: tractags/tests/macros.py
===================================================================
--- tractags/tests/macros.py	(revision 14745)
+++ tractags/tests/macros.py	(working copy)
@@ -49,7 +49,13 @@
         cursor.execute("DELETE FROM permission WHERE action %s"
                        % self.db.like(), ('TAGS_%',))
 
+    def _insert_tags(self, tagspace, name, tags):
+        cursor = self.db.cursor()
+        args = [(tagspace, name, tag) for tag in tags]
+        cursor.executemany("INSERT INTO tags (tagspace,name,tag) "
+                           "VALUES (%s,%s,%s)", args)
 
+
 class TagTemplateProviderTestCase(_BaseTestCase):
 
     def setUp(self):
@@ -64,7 +70,7 @@
 
 
 class ListTaggedMacroTestCase(_BaseTestCase):
-    
+
     def setUp(self):
         _BaseTestCase.setUp(self)
         self.req = Mock(path_info='/wiki/ListTaggedPage',
@@ -82,7 +88,54 @@
                         str(self.tag_twm.expand_macro(formatter,
                                                       'ListTagged', '')))
 
+    def _test_listtagged_paginate(self, page, per_page=2):
+        self._insert_tags('wiki', 'InterTrac', ('blah',))
+        self._insert_tags('wiki', 'InterWiki', ('blah',))
+        self._insert_tags('wiki', 'WikiStart', ('blah',))
+        self.req.args['listtagged_per_page'] = per_page
+        self.req.args['listtagged_page'] = page
+        context = Mock(env=self.env, href=Href('/'), req=self.req)
+        formatter = Mock(context=context, req=self.req)
+        result = \
+            unicode(self.tag_twm.expand_macro(formatter, 'ListTagged', 'blah'))
+        return result
 
+    def test_listtagged_paginate_page1(self):
+        """Paginate results for page 1 has two items."""
+        result = self._test_listtagged_paginate(1)
+        self.assertTrue('InterTrac' in result)
+        self.assertTrue('InterWiki' in result)
+        self.assertFalse('WikiStart' in result)
+
+    def test_listtagged_paginate_page2(self):
+        """Paginate results for page 2 has one item."""
+        result = self._test_listtagged_paginate(2)
+        self.assertFalse('InterTrac' in result)
+        self.assertFalse('InterWiki' in result)
+        self.assertTrue('WikiStart' in result)
+
+    def test_listtagged_paginate_page_out_of_range(self):
+        """Out of range page defaults to 1."""
+        result = self._test_listtagged_paginate(3)
+        self.assertTrue('InterTrac' in result)
+        self.assertTrue('InterWiki' in result)
+        self.assertFalse('WikiStart' in result)
+
+    def test_listtagged_paginate_page_invalid(self):
+        """Invalid page default to 1."""
+        result = self._test_listtagged_paginate(-1)
+        self.assertTrue('InterTrac' in result)
+        self.assertTrue('InterWiki' in result)
+        self.assertFalse('WikiStart' in result)
+
+    def test_listtagged_paginate_per_page_invalid(self):
+        """Invalid per_page defaults to items_per_page (100)."""
+        result = self._test_listtagged_paginate(2, -1)
+        self.assertTrue('InterTrac' in result)
+        self.assertTrue('InterWiki' in result)
+        self.assertTrue('WikiStart' in result)
+
+
 class TagCloudMacroTestCase(_BaseTestCase):
 
     def setUp(self):
@@ -102,12 +155,6 @@
     def _expand_macro(self, content):
         return self.tag_twm.expand_macro(self.formatter, 'TagCloud', content)
 
-    def _insert_tags(self, tagspace, name, tags):
-        cursor = self.db.cursor()
-        args = [(tagspace, name, tag) for tag in tags]
-        cursor.executemany("INSERT INTO tags (tagspace,name,tag) "
-                           "VALUES (%s,%s,%s)", args)
-
     # Tests
 
     def test_normal(self):
