diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## microstache 1.0.1
+
+- Add `renderMustacheW`
+
 ## microstache 1
 
 Initial release, corresponding to `stache-0.2.2`.
diff --git a/microstache.cabal b/microstache.cabal
--- a/microstache.cabal
+++ b/microstache.cabal
@@ -1,5 +1,5 @@
 name:                 microstache
-version:              1
+version:              1.0.1
 cabal-version:        >= 1.10
 license:              BSD3
 license-file:         LICENSE
@@ -65,6 +65,7 @@
     Text.Microstache.Render
     Text.Microstache.Type
   hs-source-dirs:     src
+  ghc-options:        -Wall
   default-language:   Haskell2010
 
 test-suite tests
diff --git a/mustache-spec/Spec.hs b/mustache-spec/Spec.hs
--- a/mustache-spec/Spec.hs
+++ b/mustache-spec/Spec.hs
@@ -71,7 +71,7 @@
     return (specData' bytes)
   where
     specData' bytes = describe aspect $ do
-      let handleError = expectationFailure . show 
+      let handleError = expectationFailure . show
       case eitherDecode bytes of
         Left err ->
           it "should load YAML specs first" $
@@ -88,5 +88,6 @@
                       Left perr -> handleError perr >> undefined
                       Right ns  -> return (pname, ns)
                   let ps2 = M.fromList ps1 `M.union` templateCache
-                  renderMustache (Template templateActual ps2) testData
-                    `shouldBe` testExpected
+                  let (_ws, t) = renderMustacheW (Template templateActual ps2) testData
+                  -- _ <- traverse print _ws
+                  t `shouldBe` testExpected
diff --git a/src/Text/Microstache.hs b/src/Text/Microstache.hs
--- a/src/Text/Microstache.hs
+++ b/src/Text/Microstache.hs
@@ -78,12 +78,17 @@
   , Key (..)
   , PName (..)
   , MustacheException (..)
+  , displayMustacheException
+  , MustacheWarning (..)
+  , displayMustacheWarning
     -- * Compiling
   , compileMustacheDir
   , compileMustacheFile
   , compileMustacheText
     -- * Rendering
-  , renderMustache )
+  , renderMustache
+  , renderMustacheW
+  )
 where
 
 import Text.Microstache.Compile
diff --git a/src/Text/Microstache/Compile.hs b/src/Text/Microstache/Compile.hs
--- a/src/Text/Microstache/Compile.hs
+++ b/src/Text/Microstache/Compile.hs
@@ -115,8 +115,8 @@
 withException = either (throwIO . MustacheParserException) return
 
 makeAbsolute' :: FilePath -> IO FilePath
-makeAbsolute' path =
-    fmap (matchTrailingSeparator path . F.normalise) (prependCurrentDirectory path)
+makeAbsolute' path0 =
+    fmap (matchTrailingSeparator path0 . F.normalise) (prependCurrentDirectory path0)
   where
     prependCurrentDirectory :: FilePath -> IO FilePath
     prependCurrentDirectory path =
diff --git a/src/Text/Microstache/Parser.hs b/src/Text/Microstache/Parser.hs
--- a/src/Text/Microstache/Parser.hs
+++ b/src/Text/Microstache/Parser.hs
@@ -23,7 +23,7 @@
 import Data.Maybe (catMaybes)
 import Data.Text.Lazy (Text)
 import Text.Parsec hiding ((<|>))
-import Text.Parsec.Char
+import Text.Parsec.Char ()
 import Data.Word (Word)
 import Text.Microstache.Type
 import qualified Data.Text             as T
diff --git a/src/Text/Microstache/Render.hs b/src/Text/Microstache/Render.hs
--- a/src/Text/Microstache/Render.hs
+++ b/src/Text/Microstache/Render.hs
@@ -11,19 +11,17 @@
 -- import the module, because "Text.Microstache" re-exports everything you may
 -- need, import that module instead.
 
-{-# LANGUAGE CPP               #-}
-{-# LANGUAGE OverloadedStrings #-}
-
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE OverloadedStrings  #-}
 module Text.Microstache.Render
-  ( renderMustache )
+  ( renderMustache, renderMustacheW )
 where
 
-import Control.Exception (throw)
 import Control.Monad (when, forM_, unless)
-import Control.Monad.Trans.Reader
-import Control.Monad.Trans.Writer.Lazy
+import Control.Monad.Trans.Reader (ReaderT (..), asks, local)
+import Control.Monad.Trans.State.Strict (State, modify', execState)
 import Control.Monad.Trans.Class (lift)
-import Data.Aeson
+import Data.Aeson (Value (..), encode)
 import Data.Monoid (mempty)
 import Data.Semigroup ((<>))
 import Data.Foldable (asum)
@@ -32,13 +30,10 @@
 import Data.Text (Text)
 import Data.Word (Word)
 import Text.Microstache.Type
-import qualified Data.ByteString.Lazy   as B
 import qualified Data.HashMap.Strict    as H
 import qualified Data.List.NonEmpty     as NE
 import qualified Data.Map               as M
-import qualified Data.Semigroup         as S
 import qualified Data.Text              as T
-import qualified Data.Text.Encoding     as T
 import qualified Data.Text.Lazy         as TL
 import qualified Data.Text.Lazy.Encoding     as TL
 import qualified Data.Text.Lazy.Builder as B
@@ -55,12 +50,21 @@
 -- and accumulate the result as 'B.Builder' data which is then turned into
 -- lazy 'TL.Text'.
 
-type Render a = ReaderT RenderContext (Writer B.Builder) a
+type Render a = ReaderT RenderContext (State S) a
 
--- | The render monad context.
+data S = S ([MustacheWarning] -> [MustacheWarning]) B.Builder
 
+tellWarning :: MustacheWarning -> Render ()
+tellWarning w = lift (modify' f) where
+    f (S ws b) = S (ws . (w:)) b
+
+tellBuilder :: B.Builder -> Render ()
+tellBuilder b' = lift (modify' f) where
+    f (S ws b) = S ws (b <> b')
+
+-- | The render monad context.
 data RenderContext = RenderContext
-  { rcIndent   :: Maybe Word      -- ^ Actual indentation level
+  { rcIndent   :: Maybe Word     -- ^ Actual indentation level
   , rcContext  :: NonEmpty Value -- ^ The context stack
   , rcPrefix   :: Key            -- ^ Prefix accumulated by entering sections
   , rcTemplate :: Template       -- ^ The template to render
@@ -72,14 +76,14 @@
 
 -- | Render a Mustache 'Template' using Aeson's 'Value' to get actual values
 -- for interpolation.
---
--- As of version 0.2.0, if referenced values are missing (which almost
--- always indicates some sort of mistake), 'MustacheRenderException' will be
--- thrown. The included 'Key' will indicate full path to missing value and
--- 'PName' will contain the name of active partial.
-
 renderMustache :: Template -> Value -> TL.Text
-renderMustache t =
+renderMustache t = snd . renderMustacheW t
+
+-- | Like 'renderMustache' but also return a list of warnings.
+--
+-- @since 1.0.1
+renderMustacheW :: Template -> Value -> ([MustacheWarning], TL.Text)
+renderMustacheW t =
   runRender (renderPartial (templateActual t) Nothing renderNode) t
 
 -- | Render a single 'Node'.
@@ -87,9 +91,9 @@
 renderNode :: Node -> Render ()
 renderNode (TextBlock txt) = outputIndented txt
 renderNode (EscapedVar k) =
-  lookupKey k >>= outputRaw . escapeHtml . renderValue
+  lookupKey k >>= renderValue k >>= outputRaw . escapeHtml
 renderNode (UnescapedVar k) =
-  lookupKey k >>= outputRaw . renderValue
+  lookupKey k >>= renderValue k >>= outputRaw
 renderNode (Section k ns) = do
   val <- lookupKey k
   enterSection k $
@@ -113,21 +117,23 @@
 -- | Run 'Render' monad given template to render and a 'Value' to take
 -- values from.
 
-runRender :: Render a -> Template -> Value -> TL.Text
-runRender m t v = (B.toLazyText . execWriter) (runReaderT m rc)
+runRender :: Render a -> Template -> Value -> ([MustacheWarning], TL.Text)
+runRender m t v = case execState (runReaderT m rc) (S id mempty) of
+    S ws b -> (ws [], B.toLazyText b)
   where
     rc = RenderContext
       { rcIndent   = Nothing
       , rcContext  = v :| []
       , rcPrefix   = mempty
       , rcTemplate = t
-      , rcLastNode = True }
+      , rcLastNode = True
+      }
 {-# INLINE runRender #-}
 
 -- | Output a piece of strict 'Text'.
 
 outputRaw :: Text -> Render ()
-outputRaw = lift . tell . B.fromText
+outputRaw = tellBuilder . B.fromText
 {-# INLINE outputRaw #-}
 
 -- | Output indentation consisting of appropriate number of spaces.
@@ -194,12 +200,12 @@
 lookupKey k = do
   v     <- asks rcContext
   p     <- asks rcPrefix
-  pname <- asks (templateActual . rcTemplate)
   let f x = asum (simpleLookup False (x <> k) <$> v)
   case asum (fmap (f . Key) . reverse . tails $ unKey p) of
-    -- Context Misses: Failed context lookups should be considered falsey.
-    -- throw (MustacheRenderException pname (p <> k))
-    Nothing -> return (String "")
+    Nothing -> do
+        -- Context Misses: Failed context lookups should be considered falsey.
+        tellWarning $ MustacheVariableNotFound (p <> k)
+        return (String "")
     Just  r -> return r
 
 -- | Lookup a 'Value' by traversing another 'Value' using given 'Key' as
@@ -269,10 +275,19 @@
 
 -- | Render Aeson's 'Value' /without/ HTML escaping.
 
-renderValue :: Value -> Text
-renderValue Null         = ""
-renderValue (String str) = str
-renderValue value        = (TL.toStrict . TL.decodeUtf8 . encode) value
+renderValue :: Key -> Value -> Render Text
+renderValue k v = case v of
+    Null       -> return ""
+    String str -> return str
+    Object _   -> do
+        tellWarning (MustacheDirectlyRenderedValue k)
+        render v
+    Array _    -> do
+        tellWarning (MustacheDirectlyRenderedValue k)
+        render v
+    _          -> render v
+  where
+    render = return . TL.toStrict . TL.decodeUtf8 . encode
 {-# INLINE renderValue #-}
 
 -- | Escape HTML represented as strict 'Text'.
diff --git a/src/Text/Microstache/Type.hs b/src/Text/Microstache/Type.hs
--- a/src/Text/Microstache/Type.hs
+++ b/src/Text/Microstache/Type.hs
@@ -23,7 +23,11 @@
   , Key (..)
   , showKey
   , PName (..)
-  , MustacheException (..) )
+  , MustacheException (..)
+  , displayMustacheException
+  , MustacheWarning (..)
+  , displayMustacheWarning
+  )
 where
 
 import Data.Word (Word)
@@ -109,20 +113,42 @@
 data MustacheException
   = MustacheParserException ParseError
     -- ^ Template parser has failed. This contains the parse error.
-    --
-    -- /Before version 0.2.0 it was called 'MustacheException'./
   | MustacheRenderException PName Key
     -- ^ A referenced value was not provided. The exception provides info
     -- about partial in which the issue happened 'PName' and name of the
     -- missing key 'Key'.
   deriving (Eq, Show, Typeable, Generic)
 
-#if MIN_VERSION_base(4,8,0)
-instance Exception MustacheException where
-  displayException (MustacheParserException e) = show e
-  displayException (MustacheRenderException pname key) =
+{-# DEPRECATED MustacheRenderException "Not thrown anymore, will be removed in the next major version of microstache" #-}
+
+-- | @since 1.0.1
+displayMustacheException :: MustacheException -> String
+displayMustacheException (MustacheParserException e) = show e
+displayMustacheException (MustacheRenderException pname key) =
     "Referenced value was not provided in partial \"" ++ T.unpack (unPName pname) ++
     "\", key: " ++ T.unpack (showKey key)
-#else
-instance Exception MustacheException
+
+instance Exception MustacheException where
+#if MIN_VERSION_base(4,8,0)
+    displayException = displayMustacheException
+#endif
+
+-- | @since 1.0.1
+data MustacheWarning
+  = MustacheVariableNotFound Key
+    -- ^ The template contained a variable for which there was no data counterpart in the current context
+  | MustacheDirectlyRenderedValue Key
+    -- ^ A complex value such as an Object or Array was directly rendered into the template
+  deriving (Eq, Show, Typeable, Generic)
+
+-- | @since 1.0.1
+displayMustacheWarning :: MustacheWarning -> String
+displayMustacheWarning (MustacheVariableNotFound key) = 
+    "Referenced value was not provided, key: " ++ T.unpack (showKey key)
+displayMustacheWarning (MustacheDirectlyRenderedValue key) = 
+    "Complex value rendered as such, key: " ++ T.unpack (showKey key)
+
+instance Exception MustacheWarning where
+#if MIN_VERSION_base(4,8,0)
+    displayException = displayMustacheWarning
 #endif
diff --git a/tests/Text/Microstache/RenderSpec.hs b/tests/Text/Microstache/RenderSpec.hs
--- a/tests/Text/Microstache/RenderSpec.hs
+++ b/tests/Text/Microstache/RenderSpec.hs
@@ -24,10 +24,14 @@
 
 spec :: Spec
 spec = describe "renderMustache" $ do
-  let r ns value =
+  let w ns value =
         let template = Template "test" (M.singleton "test" ns)
+        in fst (renderMustacheW template value)
+      r ns value = 
+        let template = Template "test" (M.singleton "test" ns)
         in renderMustache template value
-      key = Key . pure
+      key = Key . return
+
   it "leaves text block “as is”" $
     r [TextBlock "a text block"] Null `shouldBe` "a text block"
   it "renders escaped variables correctly" $
@@ -38,19 +42,23 @@
     r [UnescapedVar (key "foo")]
       (object ["foo" .= ("<html>&\"something\"</html>" :: Text)])
       `shouldBe` "<html>&\"something\"</html>"
+  context "when rendering a variable" $ do
+    it "warns when variable doesn't exist" $
+      w [EscapedVar (key "foo")] (object []) `shouldBe`
+        [MustacheVariableNotFound (key "foo")]
+    it "warns when variable is non-scalar" $
+      w [EscapedVar (key "foo")] (object [ "foo" .= object []]) `shouldBe`
+        [MustacheDirectlyRenderedValue (key "foo")]
   context "when rendering a section" $ do
     let nodes = [Section (key "foo") [UnescapedVar (key "bar"), TextBlock "*"]]
-    {-
-    Not correct according to spec
     context "when the key is not present" $
-      it "throws the correct exception" $
-        evaluate (r nodes (object [])) `shouldThrow`
-          (== MustacheRenderException "test" (key "foo"))
+      it "warns with the correct warning" $
+        w nodes (object []) `shouldBe`
+          [MustacheVariableNotFound (key "foo")]
     context "when the key is not present inside a section" $
-      it "throws the correct exception" $
-        evaluate (r nodes (object ["foo" .= ([1] :: [Int])])) `shouldThrow`
-          (== MustacheRenderException "test" (Key ["foo","bar"]))
-    -}
+      it "warns with the correct warning" $
+        w nodes (object ["foo" .= ([1] :: [Int])]) `shouldBe`
+          [MustacheVariableNotFound (Key ["foo","bar"])]
     context "when the key is present" $ do
       context "when the key is a “false” value" $ do
         it "skips the Null value" $
@@ -105,12 +113,10 @@
             `shouldBe` "x"
   context "when rendering an inverted section" $ do
     let nodes = [InvertedSection (key "foo") [TextBlock "Here!"]]
-    {-
     context "when the key is not present" $
-      it "throws the correct exception" $
-        evaluate (r nodes (object [])) `shouldThrow`
-          (== MustacheRenderException "test" (key "foo"))
-    -}
+      it "warns the correct warning" $
+        w nodes (object []) `shouldBe`
+          [MustacheVariableNotFound (key "foo")]
     context "when the key is present" $ do
       context "when the key is a “false” value" $ do
         it "renders with Null value" $
