PTB-ERROR: IMAGINGPIPE_FLIPTWHEN variable assignment failed on macOS (works on Windows)

Hi everyone,

I’m encountering an issue when running my experiment code on macOS using Psychtoolbox. The error message is:

PTB-ERROR: PsychPipelineProcessMacros: IMAGINGPIPE_FLIPTWHEN variable assignment failed in runtime! Skipped slot!

This happens when the code executes the following line:

lastScrOnsetTime(1) = begin(iLoop_0_cOpR).onsetTime;

As a result, Psychtoolbox is unable to show any text or image on the screen (presumably because the next flip time depends on lastScrOnsetTime, which failed to get assigned properly). The program continues to run, but nothing appears visually—presumably due to a mismatch or failure in screen flip timing.

System configuration:

  • OS: macOS (M3 Pro MacBook)
  • MATLAB: R2023b
  • Psychtoolbox: 3.0.21.0

Here’s the startup output related to my display setup:

PTB-INFO: OpenGL-Renderer is Apple :: Apple M3 Pro :: 2.1 Metal - 88.1
PTB-INFO: Renderer has 27648 MB of VRAM and a maximum 27648 MB of texture memory.
PTB-INFO: Screen 0 : Window 10 : VBL startline = 1964 : VBL Endline = -1
PTB-INFO: Will try to use mechanisms in the external display backend for accurate Flip timestamping.
PTB-INFO: Reported monitor refresh interval from operating system = 8.333333 ms [120.000000 Hz].
PTB-INFO: All startup display tests and calibrations disabled. Assuming a refresh interval of 120.000000 Hz.

Additional context:

The same code runs perfectly fine on Windows, using the same MATLAB and Psychtoolbox version, and the lastScrOnsetTime value is correctly retrieved there. Only on my macOS machine does this error appear, causing the screen to remain blank.

Questions:

  1. What might be the potential cause of this IMAGINGPIPE_FLIPTWHEN variable assignment error on macOS?
  2. Is this issue specific to the Apple M3 / Metal backend?
  3. Are there any recommended workarounds or configuration flags to resolve this and make the flip timestamping work properly?

Any insight or advice would be greatly appreciated. Thanks in advance!
Best,
Ning

Hi Ning,
Just ran into the same error message, macOS (M1 Max MacBook Pro), Matlab R2024b, * Psychtoolbox: 3.0.21.0. There’s nothing shown on the screen, but the program runs. Have to check where it happens exactly, though.
Best,
Stefan

The code path for external display backends (external to Screen()) will only be executed for Virtual/Mixed/Augmented Reality applications with the VR/AR/MR/XR backend drivers, or when using the Vulkan display backend for very high color precision output on Linux, VRR timing on Linux, HDR output on all operating systems, or finally on macOS + Apple Silicon Macs. Insofar you would not use this code path for bog-standard conventional visual stimulation under anything but Apple Silicon Macs.

That said, this error has never ever been observed under any display backend mentioned above, operating system or Matlab/Octave version in any scenario under any load since it was introduced 8 years ago, and it should be essentially impossible to happen. And it has not ever happened in 1 year of testing on Apple Silicon Macs with 8 GB or 16 GB RAM under Matlab R2023b, R2024a or R2024b.

It means that the Matlab mex api function mexPutVariable() failed for some reason, and the only reason Mathworks lists for that function failing is if an input value is invalid / NULL, which in turn could only happen if the Matlab mex api function mxCreateNumericArray() would fail, which is supposed to be impossible, unless Matlab runs completely out of heap memory - but that would cause a very different type of error message.

So there is no known way this error can happen, except it now apparently happened twice, both on Apple Silicon. Very mysterious…

So does this happen with any of our demos, or can you provide a minimal demo where this happens? Does it happen only occassionally? Or after a certain runtime of the script?

For me it happened when I run EyeLink_PursuitTarget.m on my Mac (I wrote a dummy EyeLink function that is called instead of the original EyeLink function and that does nothing but returning valid values).

But to generate the minimal demo took me a really really long time now, and it’s absolutely strange. But here it is:

function testpsycherror
window = PsychImaging('OpenWindow', 0, GrayIndex(0)); % Open graphics window
Screen('Flip', window);
sca;
    function cleanup
    end
end

Remove the function cleanup, and it works. Very strange.

Error occurs for me using Matlab 2024b but not Octave 9.4.0 on MacBook with M4 chip, PTB version: ‘3.0.20.705643987’

Ps still broken in Matlab 2025a pre-release Update 5

In which demo or script does it happen to you?

I just ran Stefan’s function testpsycherror

The reproducer script and testing helped greatly, thanks!

So it appears that script hits a serious limitation of Matlabs interpreter itself, but apparently not a bug according to their docs, but something they define as “just how things are”. I beg to differ, and would call it a design flaw, but it is what it is. Details and workarounds here:

https://www.mathworks.com/help/matlab/matlab_prog/resolve-error-attempt-to-add-variable-to-a-static-workspace.html

The summary is that whenever you use a nested function, like the “cleanup” function in that script, embedded into a parent function, in this case “testpsycherror”, then the variable workspaces of these functions are now “static workspaces”, and no variables can be dynamically created by load ing a workspace or mat file, eval(), feval(), assignin() or by Mex files, the latter being what Psychtoolbox Screen() mex files does for various tasks like Apple Silicon macOS Support, very-high color precision framebuffers and some of the fine-grained VRR timing support on Linux, the Vulkan display backend for HDR / WCG display on all operating systems, VR/AR/MR eXtendedReality displays, but also support for special neuroscience stimulator devices like the stuff from VPixx or CRS, and a bunch of other advanced tasks involving the imaging pipeline.

The solution or rather workaround is as dumb as it is simple: One must either abstain from use of nested functions inside functions that call Screen('Flip') etc. or predefine all variables that Screen may use, as already defined variables can get assigned new values, if they are manually predefined.

If you add these statements to the top of ‘testpsycherror’, stuff works again:

IMAGINGPIPE_FLIPTWHEN=[];
IMAGINGPIPE_FLIPVBLSYNCLEVEL=[];

Or for that matter, if you see a similar error message in other contexts, also define the variables mentioned in the error message the same way. I guess I’ll add some help text to those error messages in the future, with tips for the workaround…

So far, so dumb.

for the original bug reporter, check your code for functions that call Screen('Flip') and also contain nested functions, and modify accordingly.

Wrt. Octave, Octave doesn’t have that limitations. In fairness though, I haven’t checked if this is still true, but in the past Octave had some other limitations / missing functionality in the area of nested functions wrt. Matlab, so sufficiently complex code relying on nested functions may not work at all or as intended with Octave for those reasons.

-mario

Thank you, Mario! I agree with you, this does seem to be a design flaw.

I don’t usually use nested functions, but since the original culprit was the PsychToolBox function EyeLink_PursuitTarget.m in the EyeLinkDemos section, it might be a good idea to update that one as well.
On the other hand, it’s nothing urgent, not many people will be running EyeLink-related functions on a Mac, I suspect.

Stefan

1 Like

Hi Stefan,

thanks for that info! Lacking an Eyelink myself, I’m only able to test in simulation mode, and the update of all the Eyelink toolbox and demos in collaboration with our partner SR-Research was massive a while ago, so these are little bits that got missed. I’ll have a look at those demos for a future release, to see if/how they could be fixed.

-mario