diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # Changelog
 
+## [0.2.0.0] -- 2024-07-18
+
+### Changed
+
+* Fixed that the settings check could not be run with arguments.
+* Added a lint to check that `long` isn't used without `option` or `switch`.
+* Added a lint to check that `many` cannot be used with a parser that can succeed without consuming anything.
+
 ## [0.1.0.0] - 2024-07-16
 
 ### Changed
diff --git a/opt-env-conf.cabal b/opt-env-conf.cabal
--- a/opt-env-conf.cabal
+++ b/opt-env-conf.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           opt-env-conf
-version:        0.1.0.0
+version:        0.2.0.0
 synopsis:       Settings parsing for Haskell: command-line arguments, environment variables, and configuration values.
 homepage:       https://github.com/NorfairKing/opt-env-conf#readme
 bug-reports:    https://github.com/NorfairKing/opt-env-conf/issues
diff --git a/src/OptEnvConf/Lint.hs b/src/OptEnvConf/Lint.hs
--- a/src/OptEnvConf/Lint.hs
+++ b/src/OptEnvConf/Lint.hs
@@ -46,11 +46,13 @@
   | LintErrorNoDashedForOption
   | LintErrorNoMetavarForOption
   | LintErrorNoDashedForSwitch
+  | LintErrorNoOptionOrSwitchForDashed
   | LintErrorNoReaderForEnvVar
   | LintErrorNoMetavarForEnvVar
   | LintErrorNoCommands
   | LintErrorUnreadableExample !String
   | LintErrorConfigWithoutLoad
+  | LintErrorManyInfinite
 
 renderLintErrors :: NonEmpty LintError -> [Chunk]
 renderLintErrors =
@@ -156,6 +158,17 @@
               "."
             ]
           ]
+        LintErrorNoOptionOrSwitchForDashed ->
+          [ [ functionChunk "long",
+              " or ",
+              functionChunk "short",
+              " has no ",
+              functionChunk "option",
+              " or ",
+              functionChunk "switch",
+              "."
+            ]
+          ]
         LintErrorNoReaderForEnvVar ->
           [ [ functionChunk "env",
               " has no ",
@@ -183,6 +196,12 @@
           [ [ functionChunk "conf",
               " was called with no way to load configuration."
             ]
+          ]
+        LintErrorManyInfinite ->
+          [ [ functionChunk "many",
+              " was called with a parser that may succeed without consuming anything."
+            ],
+            ["This is not allowed because the parser would run infinitely."]
           ],
       maybe [] (pure . ("Defined at: " :) . pure . fore cyan . chunk . T.pack . prettySrcLoc) lintErrorSrcLoc
     ]
@@ -198,22 +217,41 @@
     . runValidationT
     . go
   where
-    go :: Parser a -> ValidationT LintError (Reader Bool) ()
+    -- Returns whether 'many' is allowed.
+    -- 'many' is allowed only when every parse below consumes something.
+    go :: Parser a -> ValidationT LintError (Reader Bool) Bool
     go = \case
-      ParserPure _ -> pure ()
-      ParserAp p1 p2 -> go p1 *> go p2
-      ParserSelect p1 p2 -> go p1 *> go p2
-      ParserEmpty _ -> pure ()
-      ParserAlt p1 p2 -> go p1 *> go p2
-      -- TODO lint if we don't try to parse anything consuming under many.
-      ParserMany p -> go p
+      ParserPure _ -> pure False
+      ParserAp p1 p2 -> do
+        c1 <- go p1
+        c2 <- go p2
+        pure (c1 || c2)
+      ParserSelect p1 p2 -> do
+        c1 <- go p1
+        c2 <- go p2
+        pure (c1 || c2) -- TODO: is this right?
+      ParserEmpty _ -> pure True
+      ParserAlt p1 p2 -> do
+        c1 <- go p1
+        c2 <- go p2
+        pure (c1 && c2) -- TODO: is this right?
+        -- TODO lint if we don't try to parse anything consuming under many.
+      ParserMany p -> do
+        c <- go p
+        when (not c) $
+          mapValidationTFailure (LintError Nothing) $
+            validationTFailure LintErrorManyInfinite
+        pure c
       ParserAllOrNothing _ p -> go p
       ParserCheck _ _ _ p -> go p
       ParserCommands mLoc ls -> do
         if null ls
           then validationTFailure $ LintError mLoc LintErrorNoCommands
-          else traverse_ (go . commandParser) ls
-      ParserWithConfig p1 p2 -> go p1 *> local (const True) (go p2)
+          else and <$> traverse (go . commandParser) ls -- TODO is this right?
+      ParserWithConfig p1 p2 -> do
+        c1 <- go p1
+        c2 <- local (const True) (go p2)
+        pure $ c1 || c2
       ParserSetting mLoc Setting {..} -> mapValidationTFailure (LintError mLoc) $ do
         case settingHelp of
           Nothing ->
@@ -246,6 +284,8 @@
           validationTFailure LintErrorNoMetavarForOption
         when (isJust settingSwitchValue && null settingDasheds) $
           validationTFailure LintErrorNoDashedForSwitch
+        when (not settingTryOption && isNothing settingSwitchValue && not (null settingDasheds)) $
+          validationTFailure LintErrorNoOptionOrSwitchForDashed
         when (isJust settingEnvVars && null settingReaders) $
           validationTFailure LintErrorNoReaderForEnvVar
         when (isJust settingEnvVars && not settingHidden && isNothing settingMetavar) $
@@ -257,3 +297,11 @@
         hasConfig <- ask
         when (isJust settingConfigVals && not hasConfig) $
           validationTFailure LintErrorConfigWithoutLoad
+        pure $
+          -- 'many' is only allowed if something is being consumed and it's
+          -- impossible for nothing to be consumed.
+          and
+            [ settingTryArgument || settingTryOption || isJust settingSwitchValue,
+              null settingEnvVars,
+              null settingConfigVals
+            ]
diff --git a/src/OptEnvConf/Run.hs b/src/OptEnvConf/Run.hs
--- a/src/OptEnvConf/Run.hs
+++ b/src/OptEnvConf/Run.hs
@@ -188,95 +188,100 @@
 
 internalParser :: Version -> Parser a -> Parser (Internal a)
 internalParser version p =
-  choice
-    [ setting
-        [ switch ShowHelp,
-          short 'h',
-          long "help",
-          help "Show this help text"
-        ],
-      setting
-        [ switch ShowVersion,
-          long "version",
-          help $ "Output version information: " <> showVersion version
-        ],
-      setting
-        [ switch RenderMan,
-          long "render-man-page",
-          hidden,
-          help "Show this help text"
-        ],
-      setting
-        [ switch CheckSettings,
-          long $ NE.toList settingsCheckSwitch,
-          hidden,
-          help "Run the parser and exit if parsing succeeded."
-        ],
-      BashCompletionScript
-        <$> mapIO
-          parseAbsFile
-          ( setting
-              [ option,
-                reader str,
-                long "bash-completion-script",
+  let allowLeftovers :: Parser a -> Parser a
+      allowLeftovers p' = fst <$> ((,) <$> p' <*> many (setting [reader str, argument, hidden] :: Parser String))
+   in choice
+        [ allowLeftovers $
+            setting
+              [ switch ShowHelp,
+                short 'h',
+                long "help",
+                help "Show this help text"
+              ],
+          allowLeftovers $
+            setting
+              [ switch ShowVersion,
+                long "version",
+                help $ "Output version information: " <> showVersion version
+              ],
+          setting
+            [ switch RenderMan,
+              long "render-man-page",
+              hidden,
+              help "Show this help text"
+            ],
+          allowLeftovers $
+            setting
+              [ switch CheckSettings,
+                long $ NE.toList settingsCheckSwitch,
                 hidden,
-                help "Render the bash completion script"
-              ]
-          ),
-      ZshCompletionScript
-        <$> mapIO
-          parseAbsFile
-          ( setting
-              [ option,
-                reader str,
-                long "zsh-completion-script",
+                help "Run the parser and exit if parsing succeeded."
+              ],
+          BashCompletionScript
+            <$> mapIO
+              parseAbsFile
+              ( setting
+                  [ option,
+                    reader str,
+                    long "bash-completion-script",
+                    hidden,
+                    help "Render the bash completion script"
+                  ]
+              ),
+          ZshCompletionScript
+            <$> mapIO
+              parseAbsFile
+              ( setting
+                  [ option,
+                    reader str,
+                    long "zsh-completion-script",
+                    hidden,
+                    help "Render the zsh completion script"
+                  ]
+              ),
+          ZshCompletionScript
+            <$> mapIO
+              parseAbsFile
+              ( setting
+                  [ option,
+                    reader str,
+                    long "fish-completion-script",
+                    hidden,
+                    help "Render the fish completion script"
+                  ]
+              ),
+          setting
+            [ help "Query completion",
+              switch CompletionQuery,
+              -- Long string that no normal user would ever use.
+              long "query-opt-env-conf-completion",
+              hidden
+            ]
+            <*> setting
+              [ switch True,
+                long "completion-enriched",
+                value False,
                 hidden,
-                help "Render the zsh completion script"
+                help "Whether to enable enriched completion"
               ]
-          ),
-      ZshCompletionScript
-        <$> mapIO
-          parseAbsFile
-          ( setting
+            <*> setting
               [ option,
-                reader str,
-                long "fish-completion-script",
+                reader auto,
+                long "completion-index",
                 hidden,
-                help "Render the fish completion script"
+                help "The index between the arguments where completion was invoked."
               ]
-          ),
-      setting
-        [ help "Query completion",
-          switch CompletionQuery,
-          -- Long string that no normal user would ever use.
-          long "query-opt-env-conf-completion",
-          hidden
+            <*> many
+              ( setting
+                  [ option,
+                    reader str,
+                    long "completion-word",
+                    hidden,
+                    help "The words (arguments) that have already been typed"
+                  ]
+              ),
+          ParsedNormally <$> p
         ]
-        <*> setting
-          [ switch True,
-            long "completion-enriched",
-            value False,
-            hidden,
-            help "Whether to enable enriched completion"
-          ]
-        <*> setting
-          [ option,
-            reader auto,
-            long "completion-index",
-            hidden,
-            help "The index between the arguments where completion was invoked."
-          ]
-        <*> many
-          ( setting
-              [ option,
-                reader str,
-                long "completion-word",
-                hidden,
-                help "The words (arguments) that have already been typed"
-              ]
-          ),
-      ParsedNormally <$> p
-    ]
 
 -- | Run a parser on given arguments and environment instead of getting them
 -- from the current process.
