1. `copy_cache` in `models.py` recursively copies the caches to environment, 
2. which in
```python
def _compute_related(self, records):
        """ Compute the related field ``self`` on ``records``. """
        others = records.sudo() if self.related_sudo else records
        if records.env != others.env:
            copy_cache(records - records.filtered('id'), others.env)
        values = list(others)
        for name in self.related[:-1]:
            values = [first(value[name]) for value in values]
        for record, value in zip(records, values):
            record[self.name] = value[self.related_field.name]
```
3. copies failing cache values that have been produce previously by this line:

`models.py : def _prefetch_field()`
```python

        try:
            # THIS ONE
            result = records.read([f.name for f in fs], load='_classic_write')
        except AccessError:
            # not all records may be accessible, try with only current record
            result = self.read([f.name for f in fs], load='_classic_write')
```
I checked it's exactly the same `FailedValue` object, which is later accessed without intent (not refreshed) by the fact that the buggy environment is copied to sudo (and not refreshed).


""" Special value that encapsulates an exception instead of a value. """
    def __init__(self, exception):
        self.exception = exception
    def get(self):
        raise self.exception
def _check_value(value):
    """ Return ``value``, or call its getter if ``value`` is a :class:`SpecialValue`. """
    return value.get() if isinstance(value, SpecialValue) else value
def copy_cache(records, env):
    """ Recursively copy the cache of ``records`` to the environment ``env``. """
    src = records.env
    todo = defaultdict(set)             
    done = defaultdict(set)             
    todo[records._name].update(records._ids)
    while todo:
        model_name = next(iter(todo))
        record_ids = todo.pop(model_name) - done[model_name]
        if not record_ids:
            continue
        done[model_name].update(record_ids)
        for name, field in src[model_name]._fields.items():
            src_cache = src.cache[field]
            dst_cache = env.cache[field]
            for record_id in record_ids:
                if record_id in src_cache:
                    
                    value = dst_cache[record_id] = src_cache[record_id]
                    if field.relational and isinstance(value, tuple):
                        todo[field.comodel_name].update(value)
def first(records):