UnboundLocalError: local variable ‘video’ referenced before assignment (MovieStim initialized too late from Builder?)

If this template helps then use it. If not then just delete and start from scratch.

OS: Mac OS 2026.5.1
PsychoPy version: Studio 2026.2.1
Standard Standalone Installation? (y/n) No, PsychoPy Studio
Do you want it to also run online? (y/n) No
What are you trying to achieve?:

I am showing a Movie component (called video) where the file being shown changes by the conditions file in a trials loop.

I am not totally sure what triggered this error as it was working fine until I renamed the Routine immediately preceding the movie Routine? The renamed ITI Routine does contain a screen-freeze ITI and I did not change that name.

The task errors out when it tries to run the movie routine and returns the error:

UnboundLocalError: local variable ‘video’ referenced before assignment

I notice that in the rendered .py expt file that I can view in the Coder, all of the other Components are initialized at the beginning of the experiment by the automatic Builder code, but the video = visual.MovieStim(...) is only initialized inside the code for the movie Routine? the UnboundLocalError throws because the components = [video, ...] call at the beginning of the movie Routine cannot find the video Component (which has not been initialized at the beginning of the experiment!)

Again, I’m not sure what Builder setting I changed to change when video is auto-initialized by the Builder-code, but this happened while I was working on my task today, so it must be tied to a particular Builder setting I changed.

What did you try to make it work?:

I have patched this by adding

video=visual.MovieStim(win=win)

in a “Begin Exp” section of a Code Component in my Builder task. Initializing an empty/default Movie component this way at the beginning of the experiment allows the movie Routine to start, and then the actual Movie Component settings I have set in its Builder panel get set inside the Routine and the video appears to behave normally.

My band-aid seems to work but I wanted to flag this in case it can be patched in a longer-term fashion!

Do you have a version selected in “Use version” in Experiment Settings, or do you have moviepy/opencv/vlc selected for “Backend” in the Movie Component?

To give some history on this: This used to be a fairly common bug with Movie, because the old MovieStim classes (using moviepy, opencv and vlc) didn’t like to have .movie set after they’d been created, so Builder got around this by creating a new MovieStim object each repeat (if movie was set to “Set each repeat” or “Set during ISI”). The problem with this was exactly what you’re seeing; if you want to do anything to the MovieStim object before the Routine starts, you’d get an error because it didn’t exist yet.

When we added the ffpyplayer backend (which is now the default), we set it up so it didn’t have this problem; you can set .movie on an ffpyplayer MovieStim just fine, and Builder creates it at experiment start like any other Component.

So if you’re getting this in 2026.2.1 I would guess either you’ve got an older version selected via “Use version”, or you’re using one of the older backends. In which case I’d advise switching to ffpyplayer and a version after 2022.2.0, unless you have a particular reason not to.

Aha, thanks for explaining! Yeah, this task is descended from an ancestor task that was created in a version that could very likely have been from before 2022.2.0, so looks like I had set the movie backend all that time ago to opencv. Switching to ffplayer allowed the movie to play as expected!

Note (if this happens to anyone else): the first time I switched it to ffpyplayer and removed my patch call, I got this error that the volume attribute wasn’t set:

Traceback (most recent call last):
  File "/Volumes/mthieulab/Code/psychopy_tasks/magic_stimrating/magic_stimrating.py", line 1493, in <module>

    run(
  File "/Volumes/mthieulab/Code/psychopy_tasks/magic_stimrating/magic_stimrating.py", line 847, in run

    video.setMovie('stim/'+file)

  File "/Users/mthieu/Library/Application Support/psychopy4/.python/2026.2.1/lib/python3.11/site-packages/psychopy/visual/movies/__init__.py", line 1356, in setMovie

    self.loadMovie(value)
  File "/Users/mthieu/Library/Application Support/psychopy4/.python/2026.2.1/lib/python3.11/site-packages/psychopy/visual/movies/__init__.py", line 1526, in loadMovie

    self.volume = self._volume

    ^^^^^^^^^^^
  File "/Users/mthieu/Library/Application Support/psychopy4/.python/2026.2.1/lib/python3.11/site-packages/psychopy/visual/movies/__init__.py", line 2363, in volume

    self._player.setVolume(value)
  File "/Users/mthieu/Library/Application Support/psychopy4/.python/2026.2.1/lib/python3.11/site-packages/psychopy/visual/movies/__init__.py", line 1129, in setVolume

    volume = min(1.0, max(0.0, float(volume)))
                               ^^^^^^^^^^^^^
TypeError: float() argument must be a string or a real number, not 'NoneType'

I had checked the “No audio” box (my stimuli are video only) previously. When I unchecked the box I saw the volume field pop up so I went ahead and set the volume to 0 and then it fully worked!

I see in the hover text for the “No audio” box that it applies to moviepy and opencv only (since those have a way to open only one stream of the movie file). Is the recommendation for video-only movies with ffplayer backend to uncheck that box and set volume to 0?