{"record":{"id":"62dcbe4c41e3be77","repo":"affaan-m/ECC","slug":"target-must-be-a-distinct-versioned-timeline","errorCode":null,"errorMessage":"target must be a distinct versioned timeline","messagePattern":"target must be a distinct versioned timeline","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/resolve.py","lineNumber":256,"sourceCode":"    source_end_mode,\n    fps,\n    base_track_count,\n    probe=probe_asset,\n):\n    \"\"\"Append and verify overlays; returns an in-memory placement receipt only.\n\n    This does not save/export/render a project. Supply the selected target's\n    media pool. Existing overlay tracks must be empty; base tracks are preserved.\n    source_end_mode is required: use the endpoint convention verified on this\n    Resolve host. No automatic retry occurs if that convention is incorrect.\n    \"\"\"\n    if source_end_mode not in (\"inclusive\", \"exclusive\"):\n        raise ValueError(\"source_end_mode must be inclusive or exclusive\")\n    if not isinstance(source_timeline, str) or not source_timeline:\n        raise ValueError(\"source_timeline must be explicit\")\n    name = timeline.GetName()\n    if not name or name == source_timeline:\n        raise ValueError(\"target must be a distinct versioned timeline\")\n    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        ):","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/resolve.py#L238-L274","documentation":"The target timeline must have a non-empty name and must not be the same timeline as the source. The library enforces editing onto a distinct versioned copy so the source master timeline is never mutated. It reads the target's name via GetName() and rejects it if empty or equal to source_timeline.","triggerScenarios":"Passing the source timeline object itself as the target; a timeline whose GetName() returns None/empty (unnamed or detached timeline); typo making both name arguments identical.","commonSituations":"Automation that clones timelines but still passes the original object; Resolve timelines created via API without a name set; scripts that lost track of which handle is the duplicate.","solutions":["Duplicate the timeline first (Timeline.DuplicateTimeline or CreateCompound/Save as version) and pass the new timeline object","Compare timeline.GetName() to source_timeline in your script before calling and fail fast with a clearer message","Set an explicit name on the target timeline in Resolve","Ensure your clone/apply plumbing passes the duplicate, not the source"],"exampleFix":"// before\napply_placements(timeline, pool, placements, source_timeline=timeline.GetName(), ...)  # same timeline\n// after\ndup = pm.ImportTimeline(source_path) or timeline_media_pool.DuplicateTimeline(timeline)\napply_placements(dup, pool, placements, source_timeline=timeline.GetName(), ...)","handlingStrategy":"validation","validationCode":"name = timeline.GetName()\nif not name or name == source_timeline:\n    raise ValueError(\"duplicate the source timeline and pass the copy as target\")","typeGuard":"def is_distinct_target(timeline, source_name: str) -> bool:\n    name = timeline.GetName()\n    return isinstance(name, str) and bool(name) and name != source_name","tryCatchPattern":"try:\n    apply_placements(target, pool, ...)\nexcept ValueError as exc:\n    if \"distinct versioned timeline\" in str(exc):\n        print(\"Duplicate the source timeline before applying placements\")\n    raise","preventionTips":["Always duplicate the source timeline before automated edits","Name duplicated timelines explicitly (e.g. master_v4_overlay)","Assert target name differs from source in your pipeline script","Never pass the master timeline handle as the apply target"],"tags":["validation","timeline","safety"],"backgroundTag":"invalid-state-transition","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"}