diff --git a/src/pynwb/form/build/map.py b/src/pynwb/form/build/map.py
index 5efe6b8e..3de93323 100644
--- a/src/pynwb/form/build/map.py
+++ b/src/pynwb/form/build/map.py
@@ -15,6 +15,16 @@ from .warnings import OrphanContainerWarning, MissingRequiredWarning
 
 
 class Proxy(object):
+    """
+    A temporary object to represent a Container. This gets used when resolving the true location of a
+    Container's parent.
+
+    Proxy objects allow simple bookeeping of all potential parents a Container may have.
+
+    This object is used by providing all the necessary information for describing the object. This object
+    gets passed around and candidates are accumulated. Upon calling resolve, all saved candidates are matched
+    against the information (provided to the constructor). The candidate that has an exact match is returned.
+    """
 
     def __init__(self, manager, source, location, namespace, data_type):
         self.__source = source
@@ -24,24 +34,24 @@ class Proxy(object):
         self.__manager = manager
         self.__candidates = list()
 
-    @property
-    def candidates(self):
-        return self.__candidates
-
     @property
     def source(self):
+        """The source of the object e.g. file source"""
         return self.__source
 
     @property
     def location(self):
+        """The location of the object. This can be thought of as a unique path"""
         return self.__location
 
     @property
     def namespace(self):
+        """The namespace from which the data_type of this Proxy came from"""
         return self.__namespace
 
     @property
     def data_type(self):
+        """The data_type of Container that should match this Proxy"""
         return self.__data_type
 
     @docval({"name": "object", "type": (BaseBuilder, Container), "doc": "the container or builder to get a proxy for"})
@@ -115,8 +125,12 @@ class BuildManager(object):
         stack = list()
         tmp = container
         while tmp is not None:
-            stack.append(tmp.name)
-            tmp = tmp.parent
+            if isinstance(tmp, Proxy):
+                stack.append(tmp.location)
+                break
+            else:
+                stack.append(tmp.name)
+                tmp = tmp.parent
         loc = "/".join(reversed(stack))
         return Proxy(self, container.container_source, loc, ns, dt)
 
@@ -523,6 +537,13 @@ class ObjectMapper(with_metaclass(ExtenderMeta, object)):
             return None
         attr_val = self.__get_override_attr(attr_name, container, manager)
         if attr_val is None:
+            # TODO: A message like this should be used to warn users when an expected attribute
+            # does not exist on a Container object
+            #
+            # if not hasattr(container, attr_name):
+            #     msg = "Container '%s' (%s) does not have attribute '%s'" \
+            #             % (container.name, type(container), attr_name)
+            #     #warnings.warn(msg)
             attr_val = getattr(container, attr_name, None)
             if attr_val is not None:
                 attr_val = self.__convert_value(attr_val, spec)

FilteredEphys error on read
```python
from pynwb import NWBFile, NWBHDF5IO
from pynwb.ecephys import FilteredEphys, ElectricalSeries
import numpy as np

nwbfile = NWBFile("source", "a file with header data", "NB123A", '2018-06-01T00:00:00')

module_lfp = nwbfile.create_processing_module(
    'lfp', source='source', description='source')

filt_ephys = FilteredEphys(source='source', name='name')

device = nwbfile.create_device('device_name', 'source')
electrode_group = nwbfile.create_electrode_group(
    name='electrode_group_name',
    source='source',
    description='desc',
    device=device,
    location='unknown')

nwbfile.add_electrode(0,
                      np.nan, np.nan, np.nan,  # position?
                      imp=np.nan,
                      location='unknown',
                      filtering='unknown',
                      description='desc',
                      group=electrode_group)

etr = nwbfile.create_electrode_table_region([0], 'etr_name')

for passband in ('theta', 'gamma'):
    electrical_series = ElectricalSeries(name=passband + '_phase',
                                         source='ephys_analysis',
                                         data=[1., 2., 3.],
                                         rate=0.0,
                                         electrodes=etr)
    filt_ephys.add_electrical_series(electrical_series)

module_lfp.add_container(filt_ephys)

with NWBHDF5IO('test.nwb', 'w') as io:
    io.write(nwbfile)

with NWBHDF5IO('test.nwb', 'r') as io:
    io.read()
```

error:
```python
Traceback (most recent call last):
  File "/Users/bendichter/dev/to_nwb/test.py", line 48, in <module>
    io.read()
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/utils.py", line 330, in func_call
    return func(self, **parsed['args'])
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/backends/io.py", line 33, in read
    container = self.__manager.construct(f_builder)
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/utils.py", line 330, in func_call
    return func(self, **parsed['args'])
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/build/map.py", line 178, in construct
    self.__resolve_parents(result)
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/build/map.py", line 188, in __resolve_parents
    tmp.parent = tmp.parent.resolve()
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/build/map.py", line 60, in resolve
    if self.matches(candidate):
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/utils.py", line 330, in func_call
    return func(self, **parsed['args'])
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/build/map.py", line 50, in matches
    obj = self.__manager.get_proxy(obj)
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/utils.py", line 330, in func_call
    return func(self, **parsed['args'])
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/build/map.py", line 99, in get_proxy
    return self.__get_proxy_container(obj)
  File "/Users/bendichter/dev/pynwb/src/pynwb/form/build/map.py", line 117, in __get_proxy_container
    stack.append(tmp.name)
AttributeError: 'Proxy' object has no attribute 'name'
```

if you take out `module_lfp.add_container(filt_ephys)` it runs as expected.
diff --git a/tests/unit/form_tests/test_io_hdf5_h5tools.py b/tests/unit/form_tests/test_io_hdf5_h5tools.py
index d927f00b..4e126466 100644
--- a/tests/unit/form_tests/test_io_hdf5_h5tools.py
+++ b/tests/unit/form_tests/test_io_hdf5_h5tools.py
@@ -12,6 +12,8 @@ from pynwb.base import TimeSeries
 from pynwb import NWBHDF5IO
 from pynwb.spec import NWBNamespace, NWBGroupSpec, NWBDatasetSpec
 
+from pynwb.ecephys import ElectricalSeries
+
 
 import tempfile
 import warnings
@@ -400,6 +402,47 @@ class TestCacheSpec(unittest.TestCase):
         return types
 
 
+class TestLinkResolution(unittest.TestCase):
+
+    def test_link_resolve(self):
+        print("TEST_LINK_RESOLVE")
+
+        nwbfile = NWBFile("source", "a file with header data", "NB123A", '2018-06-01T00:00:00')
+        device = nwbfile.create_device('device_name', 'source')
+        electrode_group = nwbfile.create_electrode_group(
+            name='electrode_group_name',
+            source='source',
+            description='desc',
+            device=device,
+            location='unknown')
+        nwbfile.add_electrode(0,
+                              1.0, 2.0, 3.0,  # position?
+                              imp=2.718,
+                              location='unknown',
+                              filtering='unknown',
+                              description='desc',
+                              group=electrode_group)
+        etr = nwbfile.create_electrode_table_region([0], 'etr_name')
+        for passband in ('theta', 'gamma'):
+            electrical_series = ElectricalSeries(name=passband + '_phase',
+                                                 source='ephys_analysis',
+                                                 data=[1., 2., 3.],
+                                                 rate=0.0,
+                                                 electrodes=etr)
+            nwbfile.add_acquisition(electrical_series)
+        with NWBHDF5IO(self.path, 'w') as io:
+            io.write(nwbfile)
+        with NWBHDF5IO(self.path, 'r') as io:
+            io.read()
+
+    def setUp(self):
+        self.path = "test_link_resolve.nwb"
+
+    def tearDown(self):
+        if os.path.exists(self.path):
+            os.remove(self.path)
+
+
 class NWBHDF5IOMultiFileTest(unittest.TestCase):
     """Tests for h5tools IO tools"""
 

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2018.1.18
chardet==3.0.4
h5py==2.7.1
idna==2.6
importlib-metadata==4.8.3
iniconfig==1.1.1
numpy==1.14.2
packaging==21.3
pandas==0.19.2
pluggy==1.0.0
py==1.11.0
-e git+https://github.com/NeurodataWithoutBorders/pynwb.git@432699f83ecb4747943a6c3bfd052b9cd5d2d357#egg=pynwb
pyparsing==3.1.4
pytest==7.0.1
python-dateutil==2.7.2
pytz==2025.2
requests==2.18.4
ruamel.yaml==0.15.37
six==1.11.0
tomli==1.2.3
typing_extensions==4.1.1
urllib3==1.22
zipp==3.6.0

name: pynwb
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - certifi==2018.1.18
      - chardet==3.0.4
      - h5py==2.7.1
      - idna==2.6
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - numpy==1.14.2
      - packaging==21.3
      - pandas==0.19.2
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - python-dateutil==2.7.2
      - pytz==2025.2
      - requests==2.18.4
      - ruamel-yaml==0.15.37
      - six==1.11.0
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - urllib3==1.22
      - zipp==3.6.0
prefix: /opt/conda/envs/pynwb

tests/unit/form_tests/test_io_hdf5_h5tools.py::TestLinkResolution::test_link_resolve
tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test__chunked_iter_fill_iterator_matched_buffer_size tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test__chunked_iter_fill_iterator_unmatched_buffer_size tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test__chunked_iter_fill_list_matched_buffer_size tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test__chunked_iter_fill_numpy_matched_buffer_size tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test__chunked_iter_fill_numpy_unmatched_buffer_size tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_copy_h5py_dataset_h5dataio_input tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_copy_h5py_dataset_input tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_link_h5py_dataset_h5dataio_input tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_link_h5py_dataset_input tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_pass_through_of_recommended_chunks tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_warning_on_linking_of_regular_array tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_warning_on_non_gzip_compression tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_warning_on_setting_io_options_on_h5dataset_input tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_data_chunk_iterator tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_data_chunk_iterator_with_compression tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_iterable tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_iterable_multidimensional_array tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_iterable_multidimensional_array_compression tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_list tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_list_chunked tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_list_compress tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_list_disable_default_compress tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_list_enable_default_compress tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_list_fillvalue tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_scalar tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_dataset_string tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_table tests/unit/form_tests/test_io_hdf5_h5tools.py::H5IOTest::test_write_table_nested tests/unit/form_tests/test_io_hdf5_h5tools.py::TestCacheSpec::test_cache_spec tests/unit/form_tests/test_io_hdf5_h5tools.py::NWBHDF5IOMultiFileTest::test_copy_file_with_external_links
src/pynwb/form/build/map.py
src/pynwb/form/build/map.py