{"record":{"id":"025aa6ec656ae62b","repo":"affaan-m/ECC","slug":"source-path-does-not-match-native-clip","errorCode":null,"errorMessage":"source path does not match native clip","messagePattern":"source path does not match native clip","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":250,"sourceCode":"    if clip[\"path\"] is not None:\n        _text(clip[\"path\"])\n    _text(clip[\"name\"])\n    if type(clip[\"enabled\"]) is not bool or not isinstance(clip[\"properties\"], dict):\n        raise ValueError(\"native clip state is incomplete\")\n\n\ndef _binding(item: Any, tracks: dict, baseline: dict, *, audio: bool = False) -> tuple:\n    _object(item, {\"media\", \"track\", \"clip_index\", \"media_frames\", \"fps\",\n                   \"source_range\", \"timeline_range\"})\n    track, index = _text(item[\"track\"]), _integer(item[\"clip_index\"])\n    if not track.startswith(\"audio\" if audio else \"video\"):\n        raise ValueError(\"wrong source/audio track kind\")\n    if track not in tracks or index >= len(tracks[track]):\n        raise ValueError(\"source binding has no native clip\")\n    clip = tracks[track][index]\n    _artifact(item[\"media\"])\n    if item[\"media\"][\"path\"] != clip[\"path\"]:\n        raise ValueError(\"source path does not match native clip\")\n    if _rate(item[\"fps\"]) != _rate(baseline[\"fps\"]):\n        raise ValueError(\"source fps/retime ambiguity\")\n    duration = clip[\"end\"] - clip[\"start\"]\n    capacity = _integer(item[\"media_frames\"], 1)\n    if capacity != clip[\"left_offset\"] + duration + clip[\"right_offset\"]:\n        raise ValueError(\"source capacity does not match native offsets\")\n    source = _range(item[\"source_range\"], [clip[\"left_offset\"], clip[\"left_offset\"] + duration])\n    target = _range(item[\"timeline_range\"], [clip[\"start\"], clip[\"end\"]])\n    mapped = [clip[\"start\"] + f - clip[\"left_offset\"] for f in source]\n    if mapped != target or (audio and target != [clip[\"start\"], clip[\"end\"]]):\n        raise ValueError(\"source/audio placement must preserve native timing\")\n    return track, index\n\n\ndef _preserved_stack(protected: Any, tracks: dict, bounds: list[int]) -> list[dict]:\n    if not isinstance(protected, list) or not protected:\n        raise ValueError(\"protected intervals must be explicit and nonempty\")\n    for item in protected:","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L232-L268","documentation":"Raised by _binding when the binding's media artifact path differs from the path stored on the referenced native clip. The binding must target the same underlying media file as the native snapshot clip to guarantee deterministic application.","triggerScenarios":"item['media']['path'] is a relative or symlinked path while the snapshot clip holds an absolute path (or vice versa), a re-exported asset at a new location, or binding reuse pointing at a different render of the same media.","commonSituations":"Snapshot and bindings produced on different machines with different project root paths; media replaced/renamed after the snapshot was taken; path normalization differences (trailing slashes, case on macOS).","solutions":["Make item['media']['path'] byte-identical to the clip's path in the snapshot; regenerate both from the same export.","Normalize paths (os.path.abspath / pathlib resolve) in the same way when producing the snapshot and the bindings.","Re-take the native snapshot after any media file rename or relocation."],"exampleFix":"// before\nitem['media']['path'] = './assets/clip.mp4'  # snapshot has '/proj/assets/clip.mp4'\n// after\nitem['media']['path'] = '/proj/assets/clip.mp4'","handlingStrategy":"validation","validationCode":"for item in bindings:\n    t, i = item['track'], item['clip_index']\n    clip = snapshot['timeline_readback'][t][i]\n    assert item['media']['path'] == clip['path'], f\"path mismatch: {item['media']['path']!r} != {clip['path']!r}\"","typeGuard":"from pathlib import Path\ndef paths_match(item, clip) -> bool:\n    return Path(item['media']['path']).resolve() == Path(clip['path']).resolve()","tryCatchPattern":"try:\n    bundle = build_application_bundle(...)\nexcept ValueError as e:\n    if 'source path does not match native clip' in str(e):\n        log.error('media path drift between bindings and snapshot')\n        # regenerate snapshot + bindings from the same export, then retry\n    raise","preventionTips":["Always produce snapshot and bindings in the same export step","Use absolute, resolved paths everywhere","Re-take snapshots after moving or renaming media files"],"tags":["binding","media","path"],"backgroundTag":"resource-not-found","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"}