{"record":{"id":"df8158f2b4ed8fdc","repo":"affaan-m/ECC","slug":"could-not-create-overlay-track","errorCode":null,"errorMessage":"could not create overlay track","messagePattern":"could not create overlay track","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/resolve.py","lineNumber":275,"sourceCode":"    plan = allocate_placements(\n        placements, fps=fps, base_track_count=base_track_count, probe=probe\n    )\n    if _fps(timeline.GetSetting(\"timelineFrameRate\")) != _fps(fps):\n        raise ValueError(\"target timeline fps mismatch\")\n    count = timeline.GetTrackCount(\"video\")\n    if count < base_track_count:\n        raise ValueError(\"base_track_count exceeds target video tracks\")\n    for track in range(base_track_count + 1, count + 1):\n        if _items(timeline, \"video\", track):\n            raise ValueError(\"target overlay tracks must be empty\")\n    before = _base_snapshot(timeline, base_track_count)\n    for _ in range(count, max(event[\"track\"] for event in plan)):\n        old_count = timeline.GetTrackCount(\"video\")\n        if (\n            not timeline.AddTrack(\"video\")\n            or timeline.GetTrackCount(\"video\") != old_count + 1\n        ):\n            raise RuntimeError(\"could not create overlay track\")\n    appended = []\n    for event in plan:\n        imported = media_pool.ImportMedia([event[\"asset\"]])\n        if not imported or len(imported) != 1:\n            raise RuntimeError(f\"could not import {event['asset']}\")\n        items = media_pool.AppendToTimeline(\n            [\n                {\n                    \"mediaPoolItem\": imported[0],\n                    \"startFrame\": 0,\n                    \"endFrame\": event[\"frames\"] - (source_end_mode == \"inclusive\"),\n                    \"mediaType\": 1,\n                    \"trackIndex\": event[\"track\"],\n                    \"recordFrame\": event[\"record_frame\"],\n                }\n            ]\n        )\n        if not items or len(items) != 1:","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/resolve.py#L257-L293","documentation":"When the plan requires more overlay tracks than the target currently has, apply_placements calls timeline.AddTrack('video') in a loop and verifies the track count actually increased by exactly one each time. If Resolve's AddTrack returns False or the count does not change, it raises this RuntimeError, because placement cannot proceed without the tracks.","triggerScenarios":"Calling apply_placements whose plan targets video track indexes beyond the timeline's track count, and Resolve refuses AddTrack — e.g. hitting the project's/Resolve version's maximum track limit, or the timeline object being stale after undo/redo.","commonSituations":"Plans computed against a source with many overlay tracks applied to a target capped by Resolve's track limits; scripting a timeline retrieved from a stale resolve object; Resolve version quirks where AddTrack returns non-boolean values.","solutions":["Pre-add the needed video tracks manually (or via script) before calling apply_placements so AddTrack is never invoked.","Reduce the number of overlay tracks in placements so max(track) fits within the current track count.","Re-fetch the timeline object from the current project to avoid a stale API handle, then retry."],"exampleFix":"// before\napply_placements(tl, pool, placements, ...)  # needs V6, has V3\n// after\nwhile tl.GetTrackCount(\"video\") < max_track:\n    tl.AddTrack(\"video\")\napply_placements(tl, pool, placements, ...)","handlingStrategy":"try-catch","validationCode":"needed = max(e[\"track\"] for e in plan)\nif timeline.GetTrackCount(\"video\") < needed:\n    print(f\"resolve may cap track creation; pre-adding {needed} tracks\")","typeGuard":"def can_add_track(timeline):\n    old = timeline.GetTrackCount(\"video\")\n    ok = bool(timeline.AddTrack(\"video\"))\n    if not ok or timeline.GetTrackCount(\"video\") != old + 1:\n        return False\n    return True","tryCatchPattern":"try:\n    apply_placements(tl, pool, placements, ...)\nexcept RuntimeError as e:\n    if \"could not create overlay track\" in str(e):\n        tl = project.GetCurrentTimeline().GetTrackCount() and project.GetCurrentTimeline()\n        # re-fetch fresh timeline handle and retry once\n    else:\n        raise","preventionTips":["Pre-create all needed video tracks before calling apply_placements.","Keep overlay track counts within Resolve's documented per-timeline track limit.","Re-fetch the timeline object from the project after undo/redo to avoid stale handles."],"tags":["resolve","tracks","runtime","timeline"],"backgroundTag":"unsupported-operation","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"}