{"record":{"id":"f162b3148d52b09f","repo":"affaan-m/ECC","slug":"source-end-mode-must-be-inclusive-or-exclusive","errorCode":null,"errorMessage":"source_end_mode must be inclusive or exclusive","messagePattern":"source_end_mode must be inclusive or exclusive","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/resolve.py","lineNumber":251,"sourceCode":"    timeline,\n    media_pool,\n    placements,\n    *,\n    source_timeline,\n    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)):","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/resolve.py#L233-L269","documentation":"apply_placements requires source_end_mode to be given explicitly as 'inclusive' or 'exclusive'. Resolve hosts differ in whether the end frame is included in the source range; the library refuses to guess because a wrong guess yields off-by-one readback failures. This is validated before any timeline mutation.","triggerScenarios":"Calling apply_placements/apply without source_end_mode, or with a value like ' Inclus ive', 'end-exclusive', or None.","commonSituations":"Copy-pasting an older call signature before the parameter existed; assuming a default; typo'd enum string; writing a generic wrapper that forwards user config unvalidated.","solutions":["Pass source_end_mode=\"inclusive\" or \"exclusive\" explicitly after verifying the convention on your Resolve host","Run the mode-validation tests (test_mode_must_be_explicit_and_valid) to confirm behavior","Fix wrappers/config to forward only the two allowed strings","Add a host-verification step in your pipeline that determines the convention once and records it"],"exampleFix":"// before\napply_placements(timeline, pool, placements, fps=fps, base_track_count=2)\n// after\napply_placements(timeline, pool, placements, fps=fps, base_track_count=2, source_end_mode=\"exclusive\")","handlingStrategy":"validation","validationCode":"if source_end_mode not in (\"inclusive\", \"exclusive\"):\n    raise ValueError(\"source_end_mode must be 'inclusive' or 'exclusive'\")","typeGuard":"from typing import Literal\ndef is_valid_mode(m: str) -> bool:\n    return m in (\"inclusive\", \"exclusive\")\nMode = Literal[\"inclusive\", \"exclusive\"]","tryCatchPattern":"try:\n    apply_placements(..., source_end_mode=mode)\nexcept ValueError as exc:\n    print(f\"Fix source_end_mode: {exc}\")\n    raise","preventionTips":["Always pass source_end_mode explicitly; never rely on defaults","Determine the convention on your Resolve host once and store it in config","Use Literal[\"inclusive\",\"exclusive\"] typing at your call sites","Add the library's mode-validation tests to your CI"],"tags":["validation","enum","resolve-api"],"backgroundTag":"invalid-enum-argument","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"}