affaan-m/ECC · error · ValueError
source path does not match native clip
Error message
source path does not match native clip
What it means
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.
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.
Example fix
// before item['media']['path'] = './assets/clip.mp4' # snapshot has '/proj/assets/clip.mp4' // after item['media']['path'] = '/proj/assets/clip.mp4'
Defensive patterns
Strategy: validation
Validate before calling
for item in bindings:
t, i = item['track'], item['clip_index']
clip = snapshot['timeline_readback'][t][i]
assert item['media']['path'] == clip['path'], f"path mismatch: {item['media']['path']!r} != {clip['path']!r}" Type guard
from pathlib import Path
def paths_match(item, clip) -> bool:
return Path(item['media']['path']).resolve() == Path(clip['path']).resolve() Try / catch
try:
bundle = build_application_bundle(...)
except ValueError as e:
if 'source path does not match native clip' in str(e):
log.error('media path drift between bindings and snapshot')
# regenerate snapshot + bindings from the same export, then retry
raise Prevention
- Always produce snapshot and bindings in the same export step
- Use absolute, resolved paths everywhere
- Re-take snapshots after moving or renaming media files
When it happens
Trigger: 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.
Common situations: 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).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- source fps/retime ambiguity
- wrong source/audio track kind
- apply_local needs at least one media clip
- asset contains too few frames
- asset requires verified alpha
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/025aa6ec656ae62b.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/integration.py:250
if clip["path"] is not None:
_text(clip["path"])
_text(clip["name"])
if type(clip["enabled"]) is not bool or not isinstance(clip["properties"], dict):
raise ValueError("native clip state is incomplete")
def _binding(item: Any, tracks: dict, baseline: dict, *, audio: bool = False) -> tuple:
_object(item, {"media", "track", "clip_index", "media_frames", "fps",
"source_range", "timeline_range"})
track, index = _text(item["track"]), _integer(item["clip_index"])
if not track.startswith("audio" if audio else "video"):
raise ValueError("wrong source/audio track kind")
if track not in tracks or index >= len(tracks[track]):
raise ValueError("source binding has no native clip")
clip = tracks[track][index]
_artifact(item["media"])
if item["media"]["path"] != clip["path"]:
raise ValueError("source path does not match native clip")
if _rate(item["fps"]) != _rate(baseline["fps"]):
raise ValueError("source fps/retime ambiguity")
duration = clip["end"] - clip["start"]
capacity = _integer(item["media_frames"], 1)
if capacity != clip["left_offset"] + duration + clip["right_offset"]:
raise ValueError("source capacity does not match native offsets")
source = _range(item["source_range"], [clip["left_offset"], clip["left_offset"] + duration])
target = _range(item["timeline_range"], [clip["start"], clip["end"]])
mapped = [clip["start"] + f - clip["left_offset"] for f in source]
if mapped != target or (audio and target != [clip["start"], clip["end"]]):
raise ValueError("source/audio placement must preserve native timing")
return track, index
def _preserved_stack(protected: Any, tracks: dict, bounds: list[int]) -> list[dict]:
if not isinstance(protected, list) or not protected:
raise ValueError("protected intervals must be explicit and nonempty")
for item in protected:View on GitHub (pinned to 8321021c54)