diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # rhbzquery releases
 
+## 0.4.5 (2025-01-20)
+ Fields: quote unknown field
+ ParseArg parseField: error on empty parameter
+ User: use simple-prompt promptNonEmpty
+ Help: use ansi-wl-pprint for compatibility with recent optparse-applicative
+
 ## 0.4.4 (2021-09-06)
 - experimental '--reverse' command: converts url to args
 - add 'arch'/'platform' aliases
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -10,13 +10,13 @@
 
 ## Usage examples
 
-`rhbzquery f34 xyz` : Fedora 34 bugs for package xyz
+`rhbzquery f41 xyz` : Fedora 41 bugs for package xyz
 
 `rhbzquery closed rawhide xyz` : closed rawhide bugs for package xyz
 
 `rhbzquery --mine` : your open bugs (gets userid from `~/.bugzillarc`)
 
-`rhbzquery rhel8.4 bash` : RHEL 8.4 bash bugs
+`rhbzquery rhel9.4 bash` : RHEL 9.4 bash bugs
 
 `rhbzquery "Package Review" reporter_realname="Your Name"` : open package reviews you reported
 
@@ -24,18 +24,77 @@
 
 `rhbzquery component~bugzilla summary~bugzilla` : open bugs with component and summary containing "bugzilla"
 
-`rhbzquery --file f34 xyz` : file a bug against the xyz package in F34
+`rhbzquery component~python summary~something` : open bugs with component including "python" and summary containing "something"
 
+`rhbzquery --file f40 xyz` : file a bug against the xyz package in F40
+
 `rhbzquery --query rhel8 ...`: open an advanced bugzilla search for RHEL 8
 
 `rhbzquery xyz '<modified'`: xyz bugs not yet in MODIFIED or ON_QA, etc.
 
 ### Help
-`rhbzquery --help` describes arguments
+Help describes the arguments:
+`$ rhbzquery --help`
 
-`rhbzquery --list-fields` : lists the many fields (not all well supported yet, eg timestamps)
+```
+Bugzilla query tool
 
-`rhbzquery --list-operators` : lists the search operator types
+Usage: rhbzquery [--version] [-n|--dryrun] [-m|--mine] [-s|--server SERVER]
+                 [(-l|--list-fields) | (-o|--list-operators) | (-f|--file) |
+                   (-q|--query) | (-r|--reverse) | (-w|--api)]
+                 [[COMPONENT|STATUS|PRODUCTVERSION|FIELD=VALUE|FIELDopVALUE]...]
+
+
+  Tool for generating bugzilla queries
+
+  STATUS = {new,assigned,post,modified,on_qa,verified,release_pending,closed,
+            all (open and closed),'<STATE','>STATE'}
+  PRODUCTVERSION = {rawhide,fedora,fXY,epel,epelX,rhel8,rhel7,rhelX.Z}
+  op = search operator (eg '~' for substring: "summary~akeyword")
+
+  See https://github.com/juhp/rhbzquery#readme for examples
+
+Available options:
+  -h,--help                Show this help text
+  --version                Show version
+  -n,--dryrun              Do not open url
+  -m,--mine                My bugs
+  -s,--server SERVER       Bugzilla server [default: bugzilla.redhat.com]
+  -l,--list-fields         List query FIELDs
+  -o,--list-operators      List op search operator types
+  -f,--file                File a bug
+  -q,--query               Open advanced query page
+  -r,--reverse             Convert url query to args
+  -w,--api                 Web API query
+```
+
+`rhbzquery --list-fields` lists the many fields (not all well supported yet, eg timestamps)
+
+`$ rhbzquery --list-operators`
+
+```
+         '=' : equals (is equal to)
+        '!=' : notequals (is not equal to)
+         '~' : substring (contains the string)
+        '!~' : notsubstring (does not contain the string)
+        '=~' : regexp (matches regular expression)
+       '!=~' : notregexp (does not match regular expression)
+    '~case~' : casesubstring (contains the string (exact case))
+     '~any~' : anywordssubstr (contains any of the strings)
+     '~all~' : allwordssubstr (contains all of the strings)
+      '~no~' : nowordssubstr (contains none of the strings)
+'~anyexact=' : anyexact (is equal to any of the strings)
+'~anywords~' : anywords (contains any of the words)
+'~allwords~' : allwords (contains all of the words)
+ '~nowords~' : nowords (contains none of the words)
+   '~empty~' : isempty (is empty)
+'~notempty~' : isnotempty (is not empty)
+    '~noop~' : noop (ignore (comment out query field))
+
+content~ uses matches
+content!~ uses notmatches
+```
+lists the search operator types
 
 ## Installation
 Run `stack install` or `cabal install`.
diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -5,3 +5,6 @@
 - --count bugs (no such api though)
 - query aliases
 - abbrev for Fedora Container Images
+- component regexp/glob?
+- map nobody to nobody@fedoraproject.org
+- list users?
diff --git a/rhbzquery.cabal b/rhbzquery.cabal
--- a/rhbzquery.cabal
+++ b/rhbzquery.cabal
@@ -1,5 +1,6 @@
+cabal-version:       1.24
 name:                rhbzquery
-version:             0.4.4
+version:             0.4.5
 synopsis:            Bugzilla query tool
 description:
         A CLI tool for creating bugzilla queries for bugzilla.redhat.com.
@@ -7,7 +8,7 @@
 license-file:        LICENSE
 author:              Jens Petersen <petersen@redhat.com>
 maintainer:          Jens Petersen <petersen@redhat.com>
-copyright:           2020-2021  Jens Petersen <petersen@redhat.com>
+copyright:           2020-2025  Jens Petersen <petersen@redhat.com>
 category:            Utils
 homepage:            https://github.com/juhp/rhbzquery
 bug-reports:         https://github.com/juhp/rhbzquery/issues
@@ -15,8 +16,8 @@
 extra-doc-files:     ChangeLog.md
                      README.md
                      TODO
-cabal-version:       1.18
-tested-with:         GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.3
+tested-with:         GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7,
+                     GHC == 9.0.2, GHC == 9.2.8, GHC == 9.4.8, GHC == 9.6.6
 
 source-repository head
   type:                git
@@ -42,7 +43,9 @@
                      , optparse-applicative
                      , simple-cmd
                      , simple-cmd-args
+                     , simple-prompt
                      , text
+                     , ansi-wl-pprint
   hs-source-dirs:      src
   default-language:    Haskell2010
   ghc-options:         -Wall
@@ -70,4 +73,4 @@
     ghc-options:   -Wall
     build-depends: base >= 4 && < 5
                  , simple-cmd
-    build-tools:   rhbzquery
+    build-tool-depends:   rhbzquery:rhbzquery
diff --git a/src/Fields.hs b/src/Fields.hs
--- a/src/Fields.hs
+++ b/src/Fields.hs
@@ -21,6 +21,7 @@
 data BzFields = BzProduct
               | BzVersion
               | BzComponent
+              -- FIXME should be NonEmpty String
               | BzParameter String
               | BzMeta Char Natural
   deriving Eq
@@ -112,7 +113,7 @@
      then longname
      else if "cf_" ++ longname `elem` allBzFields
           then "cf_" ++ longname
-          else error' $ "unknown field: " ++ f
+          else error' $ "unknown field: " ++ show f
 
 -- https://bugzilla.redhat.com/query.cgi?query_format=advanced
 -- https://bugzilla.redhat.com/rest/field/bug
diff --git a/src/Help.hs b/src/Help.hs
--- a/src/Help.hs
+++ b/src/Help.hs
@@ -9,7 +9,7 @@
 #if !MIN_VERSION_base(4,11,0)
 import Data.Monoid ((<>))
 #endif
-import qualified Options.Applicative.Help.Pretty as P
+import qualified Text.PrettyPrint.ANSI.Leijen as P
 
 import ParseArg (statusList)
 
diff --git a/src/ParseArg.hs b/src/ParseArg.hs
--- a/src/ParseArg.hs
+++ b/src/ParseArg.hs
@@ -100,13 +100,15 @@
              | ArgStatusAll
              | ArgStatusBefore String
              | ArgStatusAfter String
+             -- FIXME NonEmpty String
              | ArgParameter String Operator String
              | ArgParameterEmpty String Bool
              | ArgComponent String
 
 readBzQueryArg :: String -> Maybe ArgType
 readBzQueryArg s =
-  ArgProdVer <$> readProductVersion s <|>
+  ArgProdVer <$>
+  readProductVersion s <|>
   parseStatus s <|>
   parseField s <|>
   parseComponent s
@@ -147,7 +149,10 @@
         OpUnary op _ ->
           if op `isInfixOf` ps then
             case splitOn op ps of
-              (f:val) -> Just (ArgParameter f oper (intercalate op val))
+              (f:val) ->
+                if null f
+                then error' $ "cannot have empty parameter before " ++ show ps
+                else Just (ArgParameter f oper (intercalate op val))
               _ -> Nothing
           else Nothing
         OpNull op _ ->
diff --git a/src/User.hs b/src/User.hs
--- a/src/User.hs
+++ b/src/User.hs
@@ -15,6 +15,7 @@
 import Data.Ini.Config
 import qualified Data.Text as T
 import qualified Data.Text.IO as T
+import SimplePrompt (promptNonEmpty)
 import System.Directory
 import System.Environment
 import System.FilePath
@@ -47,7 +48,7 @@
   case euser of
     Right user -> return user
     Left rc -> do
-      email <- prompt "Bugzilla Username"
+      email <- promptNonEmpty "Bugzilla Username"
       when (emailIsValid email) $ do
         writeFile rc $ "[" <> brc <> "]\nuser = " <> email <> "\n"
         putStrLn $ "Saved in " ++ rc
@@ -55,11 +56,3 @@
   where
     emailIsValid :: String -> Bool
     emailIsValid = Email.isValid . B.pack
-
-prompt :: String -> IO String
-prompt s = do
-  putStr $ s ++ ": "
-  inp <- getLine
-  if null inp
-    then prompt s
-    else return inp
diff --git a/test/tests.hs b/test/tests.hs
--- a/test/tests.hs
+++ b/test/tests.hs
@@ -13,12 +13,12 @@
 
 tests :: [([String],String)]
 tests =
-  [(["f33", "pango"],
-    "buglist.cgi?bug_status=__open__&product=Fedora&version=33&component=pango")
+  [(["f41", "pango"],
+    "buglist.cgi?bug_status=__open__&product=Fedora&version=41&component=pango")
   ,(["closed", "rawhide", "xyz"],
     "buglist.cgi?bug_status=CLOSED&product=Fedora&version=rawhide&component=xyz")
-  ,(["rhel8.3", "bash"],
-    "buglist.cgi?bug_status=__open__&product=Red%20Hat%20Enterprise%20Linux%208&version=8.3&component=bash")
+  ,(["rhel9.3", "bash"],
+    "buglist.cgi?bug_status=__open__&product=Red%20Hat%20Enterprise%20Linux%209&version=9.3&component=bash")
   ,(["rhel8", "bash"],
     "buglist.cgi?bug_status=__open__&product=Red%20Hat%20Enterprise%20Linux%208&component=bash")
   ,(["Package Review", "reporter_realname=Your Name"],
@@ -27,8 +27,8 @@
     "buglist.cgi?bug_status=__open__&f0=flagtypes.name&o0=substring&v0=fedora-review%2B")
   ,(["summary~bugzilla"],
     "buglist.cgi?bug_status=__open__&f0=short_desc&o0=substring&v0=bugzilla")
-  ,(["--file", "f33", "bugzilla"],
-    "enter_bug.cgi?product=Fedora&version=33&component=bugzilla")
+  ,(["--file", "f40", "bugzilla"],
+    "enter_bug.cgi?product=Fedora&version=40&component=bugzilla")
   ,(["--api", "fedora", "component~llvm"],
     "rest/bug?bug_status=__open__&product=Fedora&f0=component&o0=substring&v0=llvm")
   ]
