diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,18 @@
+Darcs 2.14.4, 28 April 2020
+
+  * Restored the ability to run our shell tests, at least when building
+    directly from a clone of our darcs repo. This was done by importing an
+    old version of shelly (1.7.1, the last that worked for us on Windows),
+    so that (modern) cabal picks that version instead of the newest one from
+    hackage. Then made it build with all supported ghc versions and fixed
+    all warnings.
+  * Fix the quick-and-dirty "solutions" to the MonadFail incompatibility
+    that replaced fail with error to avoid cascading MonadFail requirements
+    all over the place. This broke a number of our tests, proving it to be
+    semantically unsound, as I had expected. In most cases the correct
+    solution was to replace it with (throw . userError), or if possible with
+    (liftIO . fail).
+
 Darcs 2.14.3, 24 April 2020
 
   * Support for GHC 8.8 and GHC 8.10
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -10,74 +10,101 @@
 Compiling
 ---------
 
-Build instructions are available at <http://darcs.net/Binaries> but they may
-not be up-to-date.
-
-Here is a quick run down. The easiest way to build darcs is by using
-cabal-install version 3.2 or later. A plain
+The easiest way to build darcs is by using cabal-install version 3.2 or
+later. A plain
 
+```
 > cabal build
-
-should work out of the box with any ghc-8.x version. You may see some cabal
-warnings. Ignore them. If you want to run the tests, you need
-
-> cabal build --enable-tests
-
-This can be made permanent by using
+```
 
-> cabal configure --enable-tests
+or
 
-before building, which is useful mainly for development. Or you can combine
-building and testing:
+```
+> cabal install
+```
 
-> cabal test --test-show-details=streaming
+should work out of the box with any ghc version from 8.0 up to 8.10.
 
-You can also run
+Run the test suite
+------------------
 
-> cabal install
+It is currently not possible to run the full test suite from the source
+distribution that you get from hackage. Instead you need to be in a clone of
+the darcs source code repository. This is because the tests depend on an old
+version of shelly that was patched to work with newer ghc versions and
+bundled with Darcs. It is not part of the source distribution to avoid
+'cabal install' also trying to install our patched version of shelly.
 
-to install the library and the executable.
+```
+> cabal build --enable-tests
+> cabal test --test-show-details=direct
+```
 
 Using
 -----
 
-To clone a repository from HTTP and send patches by mail:
+To clone a repository via HTTP and send patches by mail:
 
-    $ darcs clone --lazy http://darcs.net
-    $ (edit files)
-    $ darcs add (new files)
-    $ darcs record -m "my changes"
-    $ darcs send
+```
+> darcs clone --lazy http://darcs.net
+> # edit files...
+> darcs add my_new_file
+> darcs record -m "my changes"
+> darcs send
+```
 
-To clone from SSH and push patches:
+To clone via SSH and push patches:
 
-    $ darcs clone user@hub.darcs.net:user/repo
-    $ (edit files)
-    $ darcs add (new files)
-    $ darcs record -m "my changes"
-    $ darcs push
+```
+> darcs clone user@hub.darcs.net:user/repo
+> # edit files...
+> darcs add my_new_file
+> darcs record -m "my changes"
+> darcs push
+```
 
 To create a project and start working:
 
-    $ darcs init (project)
-    $ cd (project)
-    $ (add files)
-    $ darcs add (files)
-    $ darcs record -m "initial version"
+```
+> darcs init my_project
+> cd my_project
+> # create and edit files...
+> darcs add my_new_file
+> darcs record -m "initial version"
+```
 
-See <http://darcs.net/Using> for more information.
+Pull new patches from upstream:
 
+```
+> darcs pull
+```
+
+Concise and up-to-date documentation is available from darcs itself:
+
+```
+> darcs help # list all commands
+> darcs help command # help for specific command
+> darcs command --help # dito
+```
+
 Reporting bugs
 ==============
 
-Please send bug reports to <bugs@darcs.net>.
+Please send bug reports to <bugs@darcs.net>. This will automatically add
+your report to the bug tracker. If you are unsure or just have a question or
+a comment, you can subscribe to darcs-users@darcs.net and post your question
+or comments there. See http://darcs.net/MailingLists for details.
 
+
 Hacking
 =======
 
-Please consult <http://darcs.net/Development/GettingStarted> for
-up-to-date information about contributing to Darcs.
+Please consult <http://darcs.net/Development/GettingStarted> for information
+about how to contribute to Darcs. Or send an email to darcs-devel@darcs.net
+or to darcs-users@darcs.net.
 
 The wiki can be downloaded with the command:
 
-    $ darcs clone --lazy http://darcs.net/darcs-wiki
+```
+> darcs clone --lazy http://darcs.net/darcs-wiki
+```
diff --git a/darcs.cabal b/darcs.cabal
--- a/darcs.cabal
+++ b/darcs.cabal
@@ -1,6 +1,6 @@
 cabal-version:  1.24
 Name:           darcs
-version:        2.14.3
+version:        2.14.4
 License:        GPL-2
 License-file:   COPYING
 Author:         David Roundy <droundy@darcs.net>, <darcs-devel@darcs.net>
@@ -31,6 +31,9 @@
                   This smartness lets you respond to changing demands
                   in ways that would otherwise not be possible. Learn
                   more about spontaneous branches with darcs.
+                .
+                * Please note that hackage does not correctly display
+                  the license. It is meant to be "GPL-2.0-or-later".
 Homepage:       http://darcs.net/
 
 Build-Type:     Custom
diff --git a/release/distributed-context b/release/distributed-context
--- a/release/distributed-context
+++ b/release/distributed-context
@@ -1,1 +1,1 @@
-Just "\nContext:\n\n\n[TAG 2.14.3\nBen Franksen <ben.franksen@online.de>**20200426190656\n Ignore-this: 21d97b8ff1af6e5d823789e49c08f75057f0a85eef34de7b605eae60501b2c1ce45e5e8dd84264da\n] \n"
+Just "\nContext:\n\n\n[TAG 2.14.4\nBen Franksen <ben.franksen@online.de>**20200429121444\n Ignore-this: 515570fbeb07f14bf8359f4c414b27f3b75f26d03b92c1b1e35b49e3bdd9efca3d444d36989d9434\n] \n"
diff --git a/src/Darcs/Patch/Depends.hs b/src/Darcs/Patch/Depends.hs
--- a/src/Darcs/Patch/Depends.hs
+++ b/src/Darcs/Patch/Depends.hs
@@ -248,10 +248,10 @@
 
 -- |'unwrapOneTagged' unfolds a single Tagged object in a PatchSet, adding the
 -- tag and patches to the PatchSet's patch list.
-unwrapOneTagged :: (Monad m) => PatchSet rt p wX wY -> m (PatchSet rt p wX wY)
+unwrapOneTagged :: PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
 unwrapOneTagged (PatchSet (ts :<: Tagged t _ tps) ps) =
-    return $ PatchSet ts (tps :<: t +<+ ps)
-unwrapOneTagged _ = error "called unwrapOneTagged with no Tagged's in the set"
+    Just $ PatchSet ts (tps :<: t +<+ ps)
+unwrapOneTagged _ = Nothing
 
 -- | @getUncovered ps@ returns the 'PatchInfo' for all the patches in
 --   @ps@ that are not depended on by anything else *through explicit
diff --git a/src/Darcs/Patch/Match.hs b/src/Darcs/Patch/Match.hs
--- a/src/Darcs/Patch/Match.hs
+++ b/src/Darcs/Patch/Match.hs
@@ -70,6 +70,8 @@
 import Prelude ()
 import Darcs.Prelude
 
+import Control.Exception ( throw )
+
 import Text.ParserCombinators.Parsec
     ( parse
     , CharParser
@@ -421,7 +423,7 @@
         Just m -> if nonrangeMatcherIsTag fs
                         then getTagS m repo
                         else getMatcherS Exclusive m repo
-        Nothing -> error "Pattern not specified in getNonrangeMatch."
+        Nothing -> throw $ userError "Pattern not specified in getNonrangeMatch."
 
 -- | @firstMatch fs@ tells whether @fs@ implies a "first match", that
 -- is if we match against patches from a point in the past on, rather
@@ -441,7 +443,7 @@
      Just (_,b) -> unpullLastN repo b -- b is chronologically earlier than a
      Nothing    ->
       case firstMatcher fs of
-               Nothing -> error "Pattern not specified in getFirstMatchS."
+               Nothing -> throw $ userError "Pattern not specified in getFirstMatchS."
                Just m -> if firstMatcherIsTag fs
                          then getTagS m repo
                          else getMatcherS Inclusive m repo
@@ -462,7 +464,7 @@
 checkMatchSyntax opts =
  case getMatchPattern opts of
   Nothing -> return ()
-  Just p  -> either error (const $ return ()) (parseMatch p::Either String (MatchFun rt DummyPatch))
+  Just p  -> either (throw . userError) (const $ return ()) (parseMatch p::Either String (MatchFun rt DummyPatch))
 
 getMatchPattern :: [MatchFlag] -> Maybe String
 getMatchPattern [] = Nothing
@@ -718,7 +720,7 @@
 getMatcherS ioe m repo =
     if matchExists m repo
     then applyInvToMatcher ioe m repo
-    else error $ "Couldn't match pattern "++ show m
+    else throw $ userError $ "Couldn't match pattern "++ show m
 
 getTagS :: (ApplyMonad (ApplyState p) m, MonadProgress m, Matchable p) =>
              Matcher rt p -> PatchSet rt p Origin wX -> m ()
diff --git a/src/Darcs/Patch/Prim/V1/Apply.hs b/src/Darcs/Patch/Prim/V1/Apply.hs
--- a/src/Darcs/Patch/Prim/V1/Apply.hs
+++ b/src/Darcs/Patch/Prim/V1/Apply.hs
@@ -26,6 +26,8 @@
 import Darcs.Util.ByteString ( unlinesPS )
 import Darcs.Util.Printer( renderString )
 
+import Control.Exception ( throw )
+
 import qualified Data.ByteString            as B
 import qualified Data.ByteString.Internal   as BI
 import qualified Data.ByteString.Char8 as BC (pack, unpack, unlines)
@@ -40,13 +42,13 @@
     apply (FP f (TokReplace t o n)) = mModifyFilePS f doreplace
         where doreplace fc =
                   case tryTokReplace t (BC.pack o) (BC.pack n) fc of
-                  Nothing -> error $ "replace patch to " ++ fn2fp f
+                  Nothing -> throw $ userError $ "replace patch to " ++ fn2fp f
                              ++ " couldn't apply."
                   Just fc' -> return fc'
     apply (FP f (Binary o n)) = mModifyFilePS f doapply
         where doapply oldf = if o == oldf
                              then return n
-                             else error $ "binary patch to " ++ fn2fp f
+                             else throw $ userError $ "binary patch to " ++ fn2fp f
                                   ++ " couldn't apply."
     apply (DP d AddDir) = mCreateDirectory d
     apply (DP d RmDir) = mRemoveDirectory d
@@ -114,7 +116,7 @@
   case applyHunkLines h fc of
     Right fc' -> return fc'
     Left msg ->
-      error $
+      throw $ userError $
       "### Error applying:\n" ++ renderHunk h ++
       "\n### to file " ++ fn2fp f ++ ":\n" ++ BC.unpack fc ++
       "### Reason: " ++ msg
diff --git a/src/Darcs/Repository/Match.hs b/src/Darcs/Repository/Match.hs
--- a/src/Darcs/Repository/Match.hs
+++ b/src/Darcs/Repository/Match.hs
@@ -24,6 +24,8 @@
 import Prelude ()
 import Darcs.Prelude
 
+import Control.Exception ( throw )
+
 import Darcs.Patch.Match
     ( getNonrangeMatchS
     , nonrangeMatcherIsTag
@@ -60,7 +62,7 @@
 getNonrangeMatch r = withRecordedMatch r . getMatch where
   getMatch fs = case hasIndexRange fs of
     Just (n, m) | n == m -> applyNInv (n-1)
-                | otherwise -> error "Index range is not allowed for this command."
+                | otherwise -> throw $ userError "Index range is not allowed for this command."
     _ -> getNonrangeMatchS fs
 
 getOnePatchset :: (IsRepoType rt, RepoPatch p)
diff --git a/src/Darcs/Util/Tree/Monad.hs b/src/Darcs/Util/Tree/Monad.hs
--- a/src/Darcs/Util/Tree/Monad.hs
+++ b/src/Darcs/Util/Tree/Monad.hs
@@ -27,6 +27,7 @@
 import Darcs.Util.Tree
 
 import Control.Applicative( (<$>) )
+import Control.Exception ( throw )
 
 import Data.List( sortBy )
 import Data.Int( Int64 )
@@ -216,7 +217,7 @@
            t <- gets tree
            let f = findFile t p'
            case f of
-             Nothing -> error $ "No such file " ++ show p'
+             Nothing -> throw $ userError $ "No such file " ++ show p'
              Just x -> lift (readBlob x)
 
     currentDirectory = ask
@@ -251,7 +252,7 @@
            let item = find tr from'
                found_to = find tr to'
            unless (isNothing found_to) $
-                  error $ "Error renaming: destination " ++ show to ++ " exists."
+                  throw $ userError $ "Error renaming: destination " ++ show to ++ " exists."
            unless (isNothing item) $ do
                   modifyItem from Nothing
                   modifyItem to item
diff --git a/tests/renames.sh b/tests/renames.sh
--- a/tests/renames.sh
+++ b/tests/renames.sh
@@ -26,4 +26,4 @@
 
 rm -rf R && darcs init --repo R
 cd R
-runhaskell $TESTBIN/renameHelper.hs
+runghc $TESTBIN/renameHelper.hs
