oTree Forum >

DetachedInstanceError: what causes them and how to solve them?

#1 by gmdcastillo (edited )

Hi all (and Chris in particular),

When testing with bots, I sometimes see this kind of errors:

Error during __repr__ of Participant: DetachedInstanceError('Instance <Participant at 0x7f33bdf48790> is not bound to a Session; attribute refresh operation cannot proceed')

which makes the testing crash.

I had brushed them off as being a symptom of my computer being not very powerful; I thought it was something like my memory being cached on my disk at the wrong time or something.

For the bots, usually not doing things like `group = self.player.group` and then using `group` later on does the trick.


However, yesterday the error happened in production during an online experiment. The participant cannot proceed.

From what I understand, this error means that the object (here the Participant) loses his relation with the session.

If it helps, this is where I think the error appeared:

```
@staticmethod
def vars_for_template(player: Player):
    participant = player.participant
    participant_vars = participant.vars
    pd_decision_payoff = participant_vars['pd_decision_payoffs']
    pd_belief_payoff = participant_vars['pd_belief_payoffs']
    eet_payoff = participant_vars['eet_payoff']

    payoff_PD = pd_decision_payoff['payoff'] + pd_belief_payoff['payoff']
    payoff_EET = eet_payoff['payoff_kept'] + eet_payoff['payoff_received']
    participant.payoff = payoff_PD + payoff_EET
    player.total_payoff_in_money = float(participant.payoff.to_real_world_currency(player.session))

    # save in DB
    pd_decision_payoff['payoff'] = int(pd_decision_payoff['payoff'])
    pd_belief_payoff['payoff'] = int(pd_belief_payoff['payoff'])
    eet_payoff['payoff_kept'] = int(eet_payoff['payoff_kept'])
    eet_payoff['payoff_received'] = int(eet_payoff['payoff_received'])

    player.decision_payoff_computations = json.dumps(pd_decision_payoff)
    player.belief_payoff_computations = json.dumps(pd_belief_payoff)
    player.eet_payoff_computations = json.dumps(eet_payoff)

    player.decision_payoff = pd_decision_payoff['payoff']
    player.belief_payoff = pd_belief_payoff['payoff']
    player.eet_payoff_kept = eet_payoff['payoff_kept']
    player.eet_payoff_received = eet_payoff['payoff_received']

    belief_elicitation = player.session.config['belief_elicitation']

    return {
        'belief_elicitation': belief_elicitation,
        'pd_decision_payoff': pd_decision_payoff,
        'pd_belief_payoff': pd_belief_payoff,
        'eet_payoff': eet_payoff,
        'payoff_PD': payoff_PD,
        'payoff_EET': payoff_EET,
        'total_payoff': participant.payoff,
        'total_payoff_in_money': participant.payoff.to_real_world_currency(player.session)
        }
```

As you can see, nothing too crazy, I'm just computing payoffs and saving everything in the database.

Following the trail, the error originates from the class AnyModel in databse.py:

```
def __repr__(self):
    cls_name = self.__class__.__name__
    try:
        attrs = ', '.join(
            f'{k}={v}' for (k, v) in self._get_repr_attributes().items()
        )
    except Exception as exc:
        # accessing even self.id during some DB errors raises an exception,
        # which prevents errorpage.html from being shown and adds yet another
        # exception to the chain.
        attrs = '???'
        logger.warning(f'Error during __repr__ of {cls_name}: {repr(exc)}')
    return f'{cls_name}({attrs})'
```


Taking what I've learnt from bots, my guess is that the error will disappear if I replace

```
participant = player.participant
participant_vars = participant.vars
pd_decision_payoff = participant_vars['pd_decision_payoffs']
pd_belief_payoff = participant_vars['pd_belief_payoffs']
eet_payoff = participant_vars['eet_payoff']
```

by

```
pd_decision_payoff = player.participant.vars['pd_decision_payoffs']
pd_belief_payoff = player.participant.vars['pd_belief_payoffs']
eet_payoff = player.participant.vars['eet_payoff']
```

that is, not saving the participant object in a variable before accessing it, but accessing it directly.

As anyone encountered this error before? Is my diagnostic correct?

Write a reply

Set forum username