give file name/uri containing failed key in resolve errors
diff --git a/reclass/core.py b/reclass/core.py
index 3cf3721..f1de527 100644
--- a/reclass/core.py
+++ b/reclass/core.py
@@ -16,7 +16,7 @@
 import yaml
 from reclass.output.yaml_outputter import ExplicitDumper
 from reclass.datatypes import Entity, Classes, Parameters, Exports
-from reclass.errors import MappingFormatError, ClassNotFound
+from reclass.errors import MappingFormatError, ClassNotFound, ResolveError
 from reclass.defaults import AUTOMATIC_RECLASS_PARAMETERS
 
 class Core(object):
@@ -127,7 +127,11 @@
         inventory = {}
         for nodename in self._storage.enumerate_nodes():
             node = self._node_entity(nodename)
-            node.interpolate_exports()
+            try:
+                node.interpolate_exports()
+            except ResolveError as e:
+               e.export = nodename
+               raise e
             inventory[nodename] = node.exports.as_dict()
         return inventory
 
diff --git a/reclass/datatypes/exports.py b/reclass/datatypes/exports.py
index 0d33312..8fbf880 100644
--- a/reclass/datatypes/exports.py
+++ b/reclass/datatypes/exports.py
@@ -4,14 +4,14 @@
 # This file is part of reclass (http://github.com/madduck/reclass)
 #
 from parameters import Parameters
-from reclass.errors import UndefinedVariableError
+from reclass.errors import ResolveError
 from reclass.values.value import Value
 from reclass.values.valuelist import ValueList
 
 class Exports(Parameters):
 
-    def __init__(self, mapping=None, delimiter=None, options=None):
-        super(Exports, self).__init__(mapping, delimiter, options)
+    def __init__(self, mapping=None, uri=None, delimiter=None, options=None):
+        super(Exports, self).__init__(mapping, uri, delimiter, options)
 
     def __repr__(self):
         return '%s(%r, %r)' % (self.__class__.__name__, self._base,
@@ -45,8 +45,9 @@
     def _interpolate_render_from_external(self, context, path, value):
         try:
             new = value.render(context, None, self._options)
-        except UndefinedVariableError as e:
-            raise UndefinedVariableError(e.var, path)
+        except ResolveError as e:
+            e.context = path
+            raise e
         if isinstance(new, dict):
             self._render_simple_dict(new, path)
         elif isinstance(new, list):
diff --git a/reclass/datatypes/parameters.py b/reclass/datatypes/parameters.py
index f9210c7..411f631 100644
--- a/reclass/datatypes/parameters.py
+++ b/reclass/datatypes/parameters.py
@@ -16,7 +16,7 @@
 from reclass.values.mergeoptions import MergeOptions
 from reclass.values.value import Value
 from reclass.values.valuelist import ValueList
-from reclass.errors import InfiniteRecursionError, UndefinedVariableError, InterpolationError
+from reclass.errors import InfiniteRecursionError, ResolveError, InterpolationError
 
 class Parameters(object):
     '''
@@ -44,13 +44,14 @@
     DEFAULT_PATH_DELIMITER = PARAMETER_INTERPOLATION_DELIMITER
     DICT_KEY_OVERRIDE_PREFIX = PARAMETER_DICT_KEY_OVERRIDE_PREFIX
 
-    def __init__(self, mapping=None, delimiter=None, options=None):
+    def __init__(self, mapping=None, uri=None, delimiter=None, options=None):
         if delimiter is None:
             delimiter = Parameters.DEFAULT_PATH_DELIMITER
         if options is None:
             options = MergeOptions()
         self._delimiter = delimiter
         self._base = {}
+        self._uri = uri
         self._unrendered = None
         self._escapes_handled = {}
         self._has_inv_query = False
@@ -93,7 +94,7 @@
         elif isinstance(value, (Value, ValueList)):
             return value
         else:
-            return Value(value, self._delimiter)
+            return Value(value, uri=self._uri, delimiter=self._delimiter)
 
     def _wrap_list(self, source):
         return [ self._wrap_value(v) for v in source ]
@@ -107,14 +108,14 @@
         elif isinstance(cur, ValueList):
             values = cur
         else:
-            values = ValueList(Value(cur))
+            values = ValueList(Value(cur, uri=self._uri, delimiter=self._delimiter))
 
         if isinstance(new, Value):
             values.append(new)
         elif isinstance(new, ValueList):
             values.extend(new)
         else:
-            values.append(Value(new))
+            values.append(Value(new, uri=self._uri, delimiter=self._delimiter))
 
         return values
 
@@ -266,8 +267,9 @@
     def _interpolate_render_value(self, path, value, inventory):
         try:
             new = value.render(self._base, inventory, self._options)
-        except UndefinedVariableError as e:
-            raise UndefinedVariableError(e.var, path)
+        except ResolveError as e:
+            e.context = path
+            raise e
 
         if isinstance(new, dict):
             self._render_simple_dict(new, path)
diff --git a/reclass/datatypes/tests/test_parameters.py b/reclass/datatypes/tests/test_parameters.py
index 0e8de3b..2543ba9 100644
--- a/reclass/datatypes/tests/test_parameters.py
+++ b/reclass/datatypes/tests/test_parameters.py
@@ -21,7 +21,7 @@
 class TestParameters(unittest.TestCase):
 
     def _construct_mocked_params(self, iterable=None, delimiter=None):
-        p = Parameters(iterable, delimiter)
+        p = Parameters(iterable, delimiter=delimiter)
         self._base = base = p._base
         p._base = mock.MagicMock(spec_set=dict, wraps=base)
         p._base.__repr__ = mock.MagicMock(autospec=dict.__repr__,
diff --git a/reclass/errors.py b/reclass/errors.py
index d38ed84..d753306 100644
--- a/reclass/errors.py
+++ b/reclass/errors.py
@@ -33,9 +33,10 @@
             return 'No error message provided.'
 
     def exit_with_message(self, out=sys.stderr):
-        print >>out, self.message
         if self._traceback:
             print >>out, self._traceback
+        print >>out, self.message
+        print >>out
         sys.exit(self.rc)
 
 
@@ -128,19 +129,24 @@
         super(InterpolationError, self).__init__(rc=rc, msg=msg)
 
 
-class UndefinedVariableError(InterpolationError):
+class ResolveError(InterpolationError):
 
-    def __init__(self, var, context=None):
-        super(UndefinedVariableError, self).__init__(msg=None)
-        self._var = var
-        self._context = context
-    var = property(lambda self: self._var)
-    context = property(lambda self: self._context)
+    def __init__(self, var, uri=None, export=None, context=None):
+        super(ResolveError, self).__init__(msg=None)
+        self.var = var
+        self.context = context
+        self.uri = uri
+        self.export = export
 
     def _get_message(self):
-        msg = "Cannot resolve " + self._var.join(REFERENCE_SENTINELS)
-        if self._context:
-            msg += ' in the context of %s' % self._context
+        msg = ''
+        if self.export:
+            msg = '** InvQuery: %s **\n' % self.export
+        msg += "Cannot resolve " + self.var.join(REFERENCE_SENTINELS)
+        if self.context:
+            msg += ', at %s' % self.context
+        if self.uri:
+            msg += ', in %s' % self.uri
         return msg
 
     def set_context(self, context):
diff --git a/reclass/storage/yaml_git/__init__.py b/reclass/storage/yaml_git/__init__.py
index 614d481..3482423 100644
--- a/reclass/storage/yaml_git/__init__.py
+++ b/reclass/storage/yaml_git/__init__.py
@@ -224,7 +224,7 @@
     def get_node(self, name):
         file = self._nodes[name]
         blob = self._repos[self._nodes_uri.repo].get(file.id)
-        entity = YamlData.from_string(blob.data, 'git_fs://{0}#{1}/{2}'.format(self._nodes_uri.repo, self._nodes_uri.branch, file.path)).get_entity(name)
+        entity = YamlData.from_string(blob.data, 'git_fs://{0} {1} {2}'.format(self._nodes_uri.repo, self._nodes_uri.branch, file.path)).get_entity(name)
         return entity
 
     def get_class(self, name, environment):
@@ -239,7 +239,7 @@
             raise reclass.errors.NotFoundError("File " + name + " missing from " + uri.repo + " branch " + uri.branch)
         file = self._repos[uri.repo].files[uri.branch][name]
         blob = self._repos[uri.repo].get(file.id)
-        entity = YamlData.from_string(blob.data, 'git_fs://{0}#{1}/{2}'.format(uri.repo, uri.branch, file.path)).get_entity(name)
+        entity = YamlData.from_string(blob.data, 'git_fs://{0} {1} {2}'.format(uri.repo, uri.branch, file.path)).get_entity(name)
         return entity
 
     def enumerate_nodes(self):
diff --git a/reclass/storage/yamldata.py b/reclass/storage/yamldata.py
index b28db06..31cc8ff 100644
--- a/reclass/storage/yamldata.py
+++ b/reclass/storage/yamldata.py
@@ -16,12 +16,13 @@
     @classmethod
     def from_file(cls, path):
         ''' Initialise yaml data from a local file '''
-        if not os.path.isfile(path):
-            raise NotFoundError('No such file: %s' % path)
-        if not os.access(path, os.R_OK):
-            raise NotFoundError('Cannot open: %s' % path)
-        y = cls('yaml_fs://{0}'.format(path))
-        fp = file(path)
+        abs_path = os.path.abspath(path)
+        if not os.path.isfile(abs_path):
+            raise NotFoundError('No such file: %s' % abs_path)
+        if not os.access(abs_path, os.R_OK):
+            raise NotFoundError('Cannot open: %s' % abs_path)
+        y = cls('yaml_fs://{0}'.format(abs_path))
+        fp = file(abs_path)
         data = yaml.safe_load(fp)
         if data is not None:
             y._data = data
@@ -47,6 +48,9 @@
         return self._data
 
     def get_entity(self, name=None):
+        if name is None:
+            name = self._uri
+
         classes = self._data.get('classes')
         if classes is None:
             classes = []
@@ -60,15 +64,12 @@
         parameters = self._data.get('parameters')
         if parameters is None:
             parameters = {}
-        parameters = datatypes.Parameters(parameters)
+        parameters = datatypes.Parameters(parameters, uri=self._uri)
 
         exports = self._data.get('exports')
         if exports is None:
             exports = {}
-        exports = datatypes.Exports(exports)
-
-        if name is None:
-            name = self._uri
+        exports = datatypes.Exports(exports, uri=self._uri)
 
         env = self._data.get('environment', None)
 
diff --git a/reclass/values/invitem.py b/reclass/values/invitem.py
index c3af2f8..50eb388 100644
--- a/reclass/values/invitem.py
+++ b/reclass/values/invitem.py
@@ -9,7 +9,7 @@
 
 from item import Item
 from reclass.utils.dictpath import DictPath
-from reclass.errors import ExpressionError, ParseError, UndefinedVariableError
+from reclass.errors import ExpressionError, ParseError, ResolveError
 
 _OBJ = 'OBJ'
 _TEST = 'TEST'
@@ -72,7 +72,7 @@
         try:
             return path.get_value(dictionary)
         except KeyError as e:
-            raise UndefinedVariableError(str(path))
+            raise ResolveError(str(path))
 
     def _get_vars(self, var, export, parameter, value):
         if isinstance(var, str):
@@ -246,7 +246,7 @@
         try:
             return path.get_value(dictionary)
         except KeyError as e:
-            raise UndefinedVariableError(str(path))
+            raise ResolveError(str(path))
 
     def _value_expression(self, inventory):
         results = {}
diff --git a/reclass/values/item.py b/reclass/values/item.py
index 1d29ab1..4728142 100644
--- a/reclass/values/item.py
+++ b/reclass/values/item.py
@@ -5,7 +5,6 @@
 #
 
 from reclass.utils.dictpath import DictPath
-from reclass.errors import UndefinedVariableError
 
 class Item(object):
 
diff --git a/reclass/values/refitem.py b/reclass/values/refitem.py
index b97780a..a69bbf5 100644
--- a/reclass/values/refitem.py
+++ b/reclass/values/refitem.py
@@ -6,7 +6,7 @@
 
 from item import Item
 from reclass.utils.dictpath import DictPath
-from reclass.errors import UndefinedVariableError
+from reclass.errors import ResolveError
 
 class RefItem(Item):
 
@@ -31,7 +31,7 @@
             strings = [ str(i.render(context, None)) for i in self._items ]
             value = "".join(strings)
             self._refs.append(value)
-        except UndefinedVariableError as e:
+        except ResolveError as e:
             self._allRefs = False
 
     def contents(self):
@@ -50,8 +50,8 @@
         path = DictPath(self._delimiter, ref)
         try:
             return path.get_value(context)
-        except KeyError as e:
-            raise UndefinedVariableError(ref)
+        except (KeyError, TypeError) as e:
+            raise ResolveError(ref)
 
     def render(self, context, inventory):
         if len(self._items) == 1:
diff --git a/reclass/values/tests/test_value.py b/reclass/values/tests/test_value.py
index 8211dcd..1b83094 100644
--- a/reclass/values/tests/test_value.py
+++ b/reclass/values/tests/test_value.py
@@ -12,7 +12,7 @@
 from reclass.values.value import Value
 from reclass.defaults import REFERENCE_SENTINELS, \
         PARAMETER_INTERPOLATION_DELIMITER
-from reclass.errors import UndefinedVariableError, \
+from reclass.errors import ResolveError, \
         IncompleteInterpolationError, ParseError
 import unittest
 
@@ -117,7 +117,7 @@
     def test_undefined_variable(self):
         s = _var('no_such_variable')
         tv = Value(s)
-        with self.assertRaises(UndefinedVariableError):
+        with self.assertRaises(ResolveError):
             tv.render(CONTEXT, None)
 
     def test_incomplete_variable(self):
diff --git a/reclass/values/value.py b/reclass/values/value.py
index 355aab2..fcca3ba 100644
--- a/reclass/values/value.py
+++ b/reclass/values/value.py
@@ -9,13 +9,15 @@
 from listitem import ListItem
 from scaitem import ScaItem
 from reclass.defaults import PARAMETER_INTERPOLATION_DELIMITER
+from reclass.errors import ResolveError
 
 class Value(object):
 
     _parser = Parser()
 
-    def __init__(self, value, delimiter=PARAMETER_INTERPOLATION_DELIMITER):
+    def __init__(self, value, uri=None, delimiter=PARAMETER_INTERPOLATION_DELIMITER):
         self._delimiter = delimiter
+        self._uri = uri
         if isinstance(value, str):
             self._item = self._parser.parse(value, delimiter)
         elif isinstance(value, list):
@@ -48,7 +50,11 @@
             self._item.assembleRefs(context)
 
     def render(self, context, inventory, options=None):
-        return self._item.render(context, inventory)
+        try:
+            return self._item.render(context, inventory)
+        except ResolveError as e:
+            e.uri = self._uri
+            raise e
 
     def contents(self):
         return self._item.contents()
diff --git a/reclass/values/valuelist.py b/reclass/values/valuelist.py
index 38f782c..3dc9c62 100644
--- a/reclass/values/valuelist.py
+++ b/reclass/values/valuelist.py
@@ -80,8 +80,8 @@
             else:
                 new = value.render(context, inventory)
                 if isinstance(output, dict) and isinstance(new, dict):
-                    p1 = Parameters(output, value._delimiter)
-                    p2 = Parameters(new, value._delimiter)
+                    p1 = Parameters(output, delimiter=value._delimiter)
+                    p2 = Parameters(new, delimiter=value._delimiter)
                     p1.merge(p2)
                     output = p1.as_dict()
                     continue