diff --git a/exe/Main.hs b/exe/Main.hs
--- a/exe/Main.hs
+++ b/exe/Main.hs
@@ -7,6 +7,7 @@
 import Control.Monad
 import Control.Monad.IO.Class
 import Data.List (find, isPrefixOf)
+import qualified Data.List as L
 import Data.Maybe (catMaybes)
 import DynFlags (parseDynamicFlagsCmdLine, updOptLevel)
 import qualified EnumSet as EnumSet
@@ -96,7 +97,8 @@
   files <- homeSources
   mmns <- traverse parseModuleName' files
   let main' = GHC.mkModuleName "Main"
-  pure . filter (main' /=) $ catMaybes mmns
+  pure . L.nub . filter (main' /=) $ catMaybes mmns
+  -- stack often has duplicates
 
 -- removes the "+RTS ... -RTS" sections
 filterFlags :: [String] -> [String]
diff --git a/hsinspect.cabal b/hsinspect.cabal
--- a/hsinspect.cabal
+++ b/hsinspect.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.2
 name:          hsinspect
-version:       0.0.12
+version:       0.0.13
 synopsis:      Inspect Haskell source files.
 license:       GPL-3.0-or-later
 license-file:  LICENSE
@@ -31,7 +31,7 @@
     , ghc-boot
     , time
 
-  ghc-options:      -Wall -Werror=missing-home-modules
+  ghc-options:      -Wall -Werror=missing-home-modules -Werror=orphans
   default-language: Haskell2010
 
   if flag(ghcflags)
diff --git a/library/HsInspect/Index.hs b/library/HsInspect/Index.hs
--- a/library/HsInspect/Index.hs
+++ b/library/HsInspect/Index.hs
@@ -43,6 +43,9 @@
 import qualified TcRnTypes as GHC
 import qualified TyCon as GHC
 
+-- TODO export unexposed modules too, since they could be exposed by an export elsewhere
+--
+-- TODO modules that export other modules seem to be skipped, e.g. Language.Haskell.LSP.Types
 index :: GHC.GhcMonad m => m [PackageEntries]
 index = do
   dflags <- GHC.getSessionDynFlags
@@ -151,10 +154,10 @@
    in case thing of
     (GHC.AnId var) -> Just $ IdEntry m
       (shw $ GHC.idName var)
-      (shw $ GHC.idType var) -- TODO fully qualify
+      (shw $ GHC.idType var)
     (GHC.AConLike (GHC.RealDataCon dc)) -> Just $ ConEntry m
       (shw $ GHC.getName dc)
-      (shw $ GHC.dataConUserType dc) -- TODO fully qualify
+      (shw $ GHC.dataConUserType dc)
     (GHC.AConLike (GHC.PatSynCon ps)) -> Just $ PatSynEntry m
       (shw $ GHC.getName ps)
       (showSDoc dflags $ GHC.pprPatSynType ps )
@@ -188,8 +191,6 @@
 data Exported = Exported (Maybe SourcePackageId) GHC.ModuleName
   deriving (Eq, Ord)
 
--- TODO Exported should follow re-exports until they reach the original symbol.
--- Otherwise editors have to do this.
 mkExported :: GHC.DynFlags -> UnitId -> Module -> Exported
 mkExported dflags unitid m =
   let unitid' = moduleUnitId m
diff --git a/library/HsInspect/Workarounds.hs b/library/HsInspect/Workarounds.hs
--- a/library/HsInspect/Workarounds.hs
+++ b/library/HsInspect/Workarounds.hs
@@ -52,6 +52,9 @@
     liftIO . removeFile $ tmp
   let pragmas = getOptions dflags full file
       loc  = mkRealSrcLoc (mkFastString file) 1 1
+  -- FIXME strip out any GHC_OPTIONS that use -pgmF so we don't call external
+  --       tools. This also means we can lose the .ghc.path feature from the
+  --       plugin.
   (dflags', _, _) <- parseDynamicFilePragma dflags pragmas
   case unP parseHeader (mkPState dflags' full loc) of
     POk _ (L _ hsmod) -> pure (unLoc <$> pragmas, hsmod)
