diff --git a/Biobase/Secondary/Diagrams.hs b/Biobase/Secondary/Diagrams.hs
--- a/Biobase/Secondary/Diagrams.hs
+++ b/Biobase/Secondary/Diagrams.hs
@@ -10,11 +10,13 @@
 module Biobase.Secondary.Diagrams where
 
 
+import           Control.Applicative
+import           Control.Arrow
+import           Data.List (sort,groupBy,sortBy)
+import           Data.Tuple.Select (sel1,sel2)
+import           Data.Tuple (swap)
 import qualified Data.Vector.Unboxed as VU
-import Data.List (sort,groupBy,sortBy)
-import Data.Tuple.Select (sel1,sel2)
-import Data.Tuple (swap)
-import Control.Arrow
+import           Text.Printf
 
 import Biobase.Primary
 import Biobase.Secondary
@@ -155,7 +157,7 @@
 instance MkD1Secondary ([String],String) where
   mkD1S (dict,xs) = mkD1S (length xs,ps) where
     ps :: [(Int,Int)]
-    ps = dotBracket dict xs
+    ps = unsafeDotBracket dict xs
   fromD1S (D1S s) = ([], zipWith f [0..] $ VU.toList s) where
     f k (-1) = '.'
     f k p
@@ -185,8 +187,8 @@
 -- | Secondary structure parser which allows pseudoknots, if they use different
 -- kinds of brackets.
 
-dotBracket :: [String] -> String -> [(Int,Int)]
-dotBracket dict xs = sort . concatMap (f xs) $ dict where
+unsafeDotBracket :: [String] -> String -> [(Int,Int)]
+unsafeDotBracket dict xs = sort . concatMap (f xs) $ dict where
   f xs [l,r] = g 0 [] . map (\x -> if x `elem` [l,r] then x else '.') $ xs where
     g :: Int -> [Int] -> String -> [(Int,Int)]
     g _ st [] = []
@@ -196,4 +198,21 @@
     g k (s:st) (x:xs)
       | r==x = (s,k) : g (k+1) st xs
     g a b c = error $ show (a,b,c)
+
+-- | Secondary structure parser with a notion of errors. We either return a
+-- @Right@ structure, including flags, or a @Left@ error.
+
+dotBracket :: [String] -> String -> Either String ( [(Int,Int)] )
+dotBracket dict str = fmap (sort . concat) . sequence . map (f str) $ dict where
+  f ys [l,r] = g 0 [] . map (\x -> if x `elem` [l,r] then x else '.') $ ys where
+    g :: Int -> [Int] -> String -> Either String ( [(Int,Int)] )
+    g _ [] [] = pure []
+    g k st ('.':xs) = g (k+1) st xs
+    g k st (x:xs) | l==x = g (k+1) (k:st) xs
+    g k (s:st) (x:xs) | r==x = ((s,k):) <$> g (k+1) st xs
+    g k [] xs = fail $ printf "too many closing brackets at position %d: '%s' (dot-bracket: %s)" k xs str
+    g k st [] = fail $ printf "too many opening brackets, opening bracket(s) at: %s (dot-bracket: %s)" (show $ reverse st) str
+    g a b c   = fail $ printf "unspecified error: %s (dot-bracket: %s)" (show (a,b,c)) str
+  f xs lr@(_:_:_:_) = fail $ printf "unsound dictionary: %s (dot-bracket: %s)" lr str
+  f xs lr     = fail $ printf "unspecified error: dict: %s, input: %s (dot-bracket: %s)" lr xs str
 
diff --git a/BiobaseXNA.cabal b/BiobaseXNA.cabal
--- a/BiobaseXNA.cabal
+++ b/BiobaseXNA.cabal
@@ -1,5 +1,5 @@
 name:           BiobaseXNA
-version:        0.8.1.1
+version:        0.8.2.0
 author:         Christian Hoener zu Siederdissen
 maintainer:     choener@tbi.univie.ac.at
 homepage:       http://www.tbi.univie.ac.at/~choener/
@@ -44,8 +44,9 @@
     containers     >= 0.4           ,
     csv            >= 0.1.2         ,
     file-embed     >= 0.0.4.7       ,
+    mtl            >= 2.1           ,
     primitive      >= 0.5           ,
-    PrimitiveArray >= 0.5.3         ,
+    PrimitiveArray >= 0.5.4         ,
     repa           >= 3.2           ,
     text           >= 0.11          ,
     tuple          >= 0.2           ,
diff --git a/SubOptDistance.hs b/SubOptDistance.hs
--- a/SubOptDistance.hs
+++ b/SubOptDistance.hs
@@ -5,15 +5,16 @@
 
 module Main where
 
-import System.Console.CmdArgs
 import Control.Arrow
 import Data.Char (isSpace)
+import Data.Either (either)
 import Data.List
 import Data.Ord
+import System.Console.CmdArgs
 import Text.Printf
 
-import Biobase.Secondary.Diagrams
 import Biobase.Secondary
+import Biobase.Secondary.Diagrams
 
 
 
@@ -38,8 +39,8 @@
 main = do
   Options{..} <- cmdArgs options
   (sqn:xs') <- fmap lines $ getContents
-  let xs = map (\(s,e) -> (s,dotBracket ["()"] s,read e)) $ map (break isSpace) xs'
-  let q = dotBracket ["()"] structure
+  let xs = map (\(s,e) -> (s,either error id $ dotBracket ["()"] s,read e)) $ map (break isSpace) xs'
+  let q = either error id $ dotBracket ["()"] structure
   let (d,x,e) = getMinimalDistance aq qa q xs
   let distance :: Double = e - ((/100) . read $ words sqn !! 1)
   printf "%4d %s %8.2f %8.2f\n" d x e distance
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,14 @@
+0.8.2.0
+-------
+
+- dotBracket -> unsafeDotBracket
+- new 'dotBracket' function works in the error monad
+
+0.8.1.1
+-------
+
+- added T/U conversion functions
+
 0.8.1.0
 -------
 
