{"record":{"id":"11931ce46999b4d5","repo":"affaan-m/ECC","slug":"base-tracks-changed-during-overlay-placement","errorCode":null,"errorMessage":"base tracks changed during overlay placement","messagePattern":"base tracks changed during overlay placement","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"skills/taste-application/scripts/tasteforge/resolve.py","lineNumber":330,"sourceCode":"                    key: event[key]\n                    for key in (\n                        \"record_frame\",\n                        \"frames\",\n                        \"track\",\n                        \"opacity\",\n                        \"composite\",\n                    )\n                },\n                \"actual\": actual,\n            }\n        )\n    for track in range(base_track_count + 1, timeline.GetTrackCount(\"video\") + 1):\n        if len(_items(timeline, \"video\", track)) != sum(\n            e[\"track\"] == track for e in plan\n        ):\n            raise RuntimeError(\"unexpected overlay items after append\")\n    if before != _base_snapshot(timeline, base_track_count):\n        raise RuntimeError(\"base tracks changed during overlay placement\")\n    return {\n        \"timeline\": name,\n        \"source_timeline\": source_timeline,\n        \"source_end_mode\": source_end_mode,\n        \"base_track_count\": base_track_count,\n        \"fps\": float(_fps(fps)),\n        \"placements\": receipts,\n        \"preservation\": {\"base_tracks_match\": True},\n    }\n","sourceCodeStart":312,"sourceCodeEnd":340,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/resolve.py#L312-L340","documentation":"apply_placements snapshots the base tracks (tracks 1..base_track_count) before appending, then re-snapshots after all placements and property writes. If the two snapshots differ, the base edit was disturbed and it raises this RuntimeError. This guarantees the overlay application is non-destructive to the underlying timeline content.","triggerScenarios":"Resolve moving/ripple-editing base clips when appending to upper tracks (ripple/insert behavior active), a user editing the timeline concurrently, or AppendToTimeline without explicit trackIndex landing on base tracks and shifting them.","commonSituations":"Timeline 'auto track selector' or ripple settings altered by the operator; another operator/script editing the shared project during the run; base clips whose properties (opacity) were overwritten by the script writing to the wrong item index.","solutions":["Ensure no one (or no other script) touches the timeline while apply_placements runs; run against a private duplicate timeline.","Disable ripple/auto-select behaviors in the Resolve project before running.","Re-raise with a diff of before/after snapshots to identify which base clip moved, then correct the placement plan."],"exampleFix":"// before\napply_placements(shared_tl, pool, placements, ...)\n// after\ntarget = shared_tl.CreateDuplicateTimeline(\"apply-private\")\napply_placements(target, pool, placements, ...)","handlingStrategy":"validation","validationCode":"snapshot_before = [(i.GetName(), i.GetStart(), i.GetEnd())\n                   for t in range(1, base+1)\n                   for i in tl.GetItemListInTrack(\"video\", t)]\n# compare after run; if changed, discard the timeline copy","typeGuard":"def base_tracks_stable(before, after):\n    return before == after","tryCatchPattern":"try:\n    apply_placements(target, pool, placements, ...)\nexcept RuntimeError as e:\n    if \"base tracks changed\" in str(e):\n        print(\"base edit disturbed; delete duplicate and investigate ripple/auto-select settings\")\n    else:\n        raise","preventionTips":["Always apply overlays to a duplicate timeline, never the master edit.","Disable auto-track-selector and ripple behaviors in the project before scripting.","Lock the project (or work solo) so no other operator edits during the run."],"tags":["resolve","integrity","timeline","non-destructive"],"backgroundTag":"internal-invariant-violation","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}