           !!value
 
   'string':
-    coercion: (value, schema) ->
-      throw new Error('Value must be a string') if typeof value isnt 'string'
+    coercion: (keyPath, value, schema) ->
+      throw new Error("Cannot set #{keyPath}, #{JSON.stringify(value)} must be a string") if typeof value isnt 'string'
       value
 
   'null':
     # null sort of isnt supported. It will just unset in this case
-    coercion: (value, schema) ->
-      throw new Error('Value must be an object') unless value == null
+    coercion: (keyPath, value, schema) ->
+      throw new Error("Cannot set #{keyPath}, #{JSON.stringify(value)} must be null") unless value == null
       value
 
   'object':
-    coercion: (value, schema) ->
-      throw new Error('Value must be an object') if typeof value isnt 'object'
+    coercion: (keyPath, value, schema) ->
+      throw new Error("Cannot set #{keyPath}, #{JSON.stringify(value)} must be an object") unless isPlainObject(value)
       return value unless schema.properties?
+
       newValue = {}
       for prop, childSchema of schema.properties
-        continue unless prop of value
+        continue unless value.hasOwnProperty(prop)
         try
-          newValue[prop] = @executeSchemaValidators(value[prop], childSchema)
+          newValue[prop] = @executeSchemaValidators("#{keyPath}.#{prop}", value[prop], childSchema)
         catch error
-          console.warn "Error setting value #{error.message}"
+          console.warn "Error setting item in object: #{error.message}"
       newValue
 
   'array':
-    coercion: (value, schema) ->
-      throw new Error('Value must be an array') unless Array.isArray(value)
+    coercion: (keyPath, value, schema) ->
+      throw new Error("Cannot set #{keyPath}, #{JSON.stringify(value)} must be an array") unless Array.isArray(value)
       itemSchema = schema.items
       if itemSchema?
         newValue = []
         for item in value
           try
-            newValue.push @executeSchemaValidators(item, itemSchema)
+            newValue.push @executeSchemaValidators(keyPath, item, itemSchema)
           catch error
-            console.warn "Error setting value: #{error.message}"
+            console.warn "Error setting item in array: #{error.message}"
         newValue
       else
         value
 
   '*':
-    minimumAndMaximumCoercion: (value, schema) ->
+    minimumAndMaximumCoercion: (keyPath, value, schema) ->
       return value unless typeof value is 'number'
       if schema.minimum? and typeof schema.minimum is 'number'
         value = Math.max(value, schema.minimum)

        # Using `isEqual` for possibility of placing enums on array and object schemas
        return value if _.isEqual(possibleValue, value)

      throw new Error('Value is not one of the possible values')

isPlainObject = (value) ->
  _.isObject(value) and not _.isArray(value) and not _.isFunction(value) and not _.isString(value)

        value = Math.min(value, schema.maximum)
      value

    enumValidation: (keyPath, value, schema) ->
      possibleValues = schema.enum
      return value unless possibleValues? and Array.isArray(possibleValues) and possibleValues.length

