Repository navigation
[Bug]: Reordering clips rewrites imported audio tracks (bed stretched over another clip, loop pushed past the end) #1011
Description
What happens
Reordering clips under imported audio does not carry the audio with its clip: the tracks are rebuilt, and the result is stored (autosave), so it survives a restart once the undo history is gone.
Measured on v2.0.0 (macOS), 3 clips — b6cdac 0–102.1 s, 63fedd 102.1–163.97 s, d51b65 163.97–266.07 s — with a 30 s music bed across the b6cdac/63fedd junction and a looping 4 s track across 63fedd/d51b65 (both kind: music):
| before | after moving 63fedd to the end |
|
|---|---|---|
| bed fragments | b6cdac 89.869–102.1 s, 63fedd 102.1–119.869 s |
b6cdac 89.869–102.1 s, d51b65 102.1–204.2 s (offset 12231), 63fedd 204.2–221.969 s (offset 114331) |
| loop fragments | 63fedd 119.869–163.97 s, d51b65 163.97–199.977 s |
221.969–324.069 s and 324.069–385.939 s — entirely past the 266.07 s programme end |
The 30 s bed now spans 132 s and covers a clip it never touched; the loop is pushed out of the film. Moving the clip back makes it worse (bed 89.869–266.07 s, loop 266.07–430.04 s). Only Ctrl+Z restores it.
Cause
mapAllRegionCollections (src/lib/ai-edition/document/timeline.ts:396) runs every structural clip edit's audio through separateAudioLanes(reanchorAudioTracks(fn(audioTracks), …)):
fn— hererederiveAnchoredRegionviawithClipsChanged→rederiveRegionMs— moves each anchored fragment with its own clip. After a reorder that is correct, but the fragments of one track are no longer adjacent on the ruler (bed: 89.869–102.1 s and 204.2–221.969 s).reanchorAudioTracks→collapseTracksToPills(audioTracks.ts:132) folds eachtrackIdback into ONE span from the first fragment'sstartMsto the last fragment'sendMs(89.869–221.969 s). That assumes the fragments are contiguous; after a reorder the span swallows whatever clip now sits between them.anchorAudioTrackFragmentsre-ventilates that inflated span over the new layout, so the clip in the middle gets a full-length fragment, andoffsetMskeeps advancing by elapsed span (12231 → 114331), pointing past the end of a 30 s file.separateAudioLanes(audioTracks.ts:463) then sees the inflated bed overlapping the loop (samemusicrow) and shifts the whole loop pill to the bed's end — past the programme end. It shiftsstartMs/endMsonly, so the shifted fragments no longer agree with their ownclipId/sourceStartSecanchors.
Every number in the table follows from these four steps. The reanchor pass was added in 521d0bd (in v1.11.0) to repair offsetMs after re-ventilation, which copies it verbatim. A move/reorder never re-ventilates — rederiveAnchoredRegion keeps each fragment's own offsetMs, which already encodes its file position — so for these ops the pass is unnecessary and destructive.
Possible fix
- Only re-run
reanchorAudioTrackson fragments that were actually re-ventilated (orphans / never-anchored), not on anchored fragments whose clip survived; or - collapse per run of fragments that still meet on the ruler with continuous
offsetMs(the existingtakesJointest), instead of pertrackId; and - have
separateAudioLanesmove anchors with the ms, or resolve overlap without detaching fragments from their clips.
No test covers moveClip with audio tracks (timeline.test.ts, insertion.test.ts), which is how this got through.
Expected
Each audio fragment travels with the clip it was placed over (checklist "Imported audio and voice-over": "Reorder the clips underneath a track and confirm the track follows the clip it was placed over"), keeps its length and offsetMs, and no clip gains audio it never had.
Steps
- Make a project with 3 clips (e.g. drag the same recording to the timeline three times).
- Import an audio file (M) across the clip 1/clip 2 junction; import a second one across clip 2/clip 3 and turn Loop on.
- Drag clip 2 to the end.
- The first track now covers all of the old clip 3; the second is pushed past the end of the timeline. Inspect
audioTracksin the project file to see the spans.
Environment
v2.0.0 (DMG, notarized), macOS 27.0, Mac mini M1. main has no app changes since v2.0.0. Found in the v2.0.0 computer-use E2E pass (checklist line 376).
Activity
fix(timeline): copy anchored modifiers onto a duplicated clip
fix(audio): keep each take on its own clips through a clip edit (#1011)
fix(audio): relabel a joined clip's takes without re-cutting them (#1011
github-actions commentedon Oct 6, 2026
Fixed by #1045 and merged into
main.This change is assigned to the
Next Releaserelease milestone and is not necessarily available in the latest downloadable desktop release yet. It is currently marked asstatus: pending releaseuntil a packaged release containing it is published.EtienneLescot commentedon Oct 15, 2026
Moved into
v2.1.0as part of the pre-release cut.