How to Prevent UI Freezes and Crashes During Bulk Timeline Edits via UXP API?

,

Hi everyone,
I’m building a UXP plugin for Premiere Pro that auto-arranges clips on the timeline (multi-camera auto-switcher). The entry point is an async function that iterates over potentially hundreds of camera segments and places each one on the timeline.

The UXP docs say the API is asynchronous and should not block the host UI. But in practice, Premiere freezes completely for several seconds (sometimes crashes), and all clip placements appear on the timeline all at once only after the freeze ends — the UI never updates incrementally during the loop.

What the code does (simplified):

// Called once per camera segment — may run hundreds of times
async function placeClipOnTimeline({
project, editor, projectItem,
inPointSeconds, outPointSeconds,
startSeconds, videoTrackIndex, audioTrackIndex
}) {
const startTick = TickTime.createWithSeconds(startSeconds);
const inTick    = TickTime.createWithSeconds(inPointSeconds);
const outTick   = TickTime.createWithSeconds(outPointSeconds);

// Step 1: set in/out on the source clip
project.lockedAccess(() => {
project.executeTransaction((compoundAction) => {
compoundAction.addAction(
projectItem.createSetInOutPointsAction(inTick, outTick)
);
}, “Set Source InOut”);
});

// Step 2: overwrite (insert) at the timeline position
project.lockedAccess(() => {
project.executeTransaction((compoundAction) => {
compoundAction.addAction(
editor.createOverwriteItemAction(
projectItem, startTick, videoTrackIndex, audioTrackIndex
)
);
}, “Overwrite Clip”);
});

// Step 3: clear in/out after insertion
project.lockedAccess(() => {
project.executeTransaction((compoundAction) => {
compoundAction.addAction(
projectItem.createClearInOutPointsAction()
);
}, “Clear Source InOut”);
});

// Step 4: re-fetch track to find the inserted clip, then trim it
const track = await sequence.getVideoTrack(videoTrackIndex);
const items = await track.getItems();
const insertedClip = items[items.length - 1];
// … further trim actions via another executeTransaction
}

// Main loop
export async function autoSwitchCamera(cameraSegments) {
for (let i = 0; i < cameraSegments.length; i++) {
await placeClipOnTimeline({ /* params for segment i */ });
}
}

What I observe:

Premiere’s UI becomes completely unresponsive while the loop runs.

The timeline does not update incrementally — no clips appear during the freeze.

Once Premiere unfreezes, all clips appear on the timeline at once.

With 500+ segments, Premiere sometimes crashes entirely.

My questions:

Is project.lockedAccess + project.executeTransaction synchronous/blocking on the host side?

Should all three steps (set in/out → overwrite → clear in/out) be combined into a single executeTransaction so the compound action handles the sequencing internally? Already tried this but it seems like there is a race condition(?)

Is there a recommended way to yield between iterations to keep the UI responsive, or does the host lock prevent repainting regardless?

Are there a way to prevent the crash?

Any insight? would be hugely appreciated. Thanks!

See PPro segfault crash during concurrent async locked access patterns - #2 by bbb_999

I also have a plugin that does A LOT of async and locked access pattern work and have encountered this crash bug. The PPro UXP team has been notified and is working to resolve. As a short term solution, I ended up forcing ALL PPro API calls to be serialized, AND I had to reduce the number of locked access patterns as much as possible. This means combining and making my code more efficient. Seems like there is some behind the scenes async PPro API calls being done inside of UXP that we don’t have control over, hence why I had to reduce the number of locked access patterns, to reduce the chances of this race condition.

1 Like

We’re working on that one, right now…

In our case, reducing the number of lockedAccess calls is difficult because the core functionality requires placing hundreds (sometimes thousands) of short clips on the timeline. Are there any additional short-term mitigation strategies you would recommend?

Also, since we are currently in the process of porting our panel from CEP to UXP, we’d like to better understand the timeline for CEP deprecation. The documentation mentions:

“CEP extensions continue to be supported; the plan is to support both CEP and UXP for a calendar year, after which we will remove support for CEP extensibility.”

Could you clarify what “a calendar year” refers to in practice? For example:
Is this counted from Premiere Pro 25.6 release?
Do you have a more concrete timeline for when CEP support will be fully removed?

Appreciate any guidance you can share.

You can reduce the number of locked access pattern calls by grouping many actions into a group of compound actions that all gets executed in the same locked access pattern. It sounds like in your case it may be worth just waiting until the PPro team has the bugfix in place though.

1 Like

This is the ideal approach with UXP Locked Access transactions, if/when possible.

If you can group actions into a single Locked Access transaction, you’ll get infinitely better performance, and the added benefit of being grouped as a single undo item in history.

We’re doing this for removing/deleting hundreds of clips at a time with success.

The limitation comes however if transactions are dependent on previous transactions requiring them to be separate.

I’ve started a separate issue for this one, requesting Return Values for Actions so we can group dependent actions together, instead of only independent actions, without the need for separate transactions:

2 Likes