affaan-m/ECC · error · ValueError

source binding has no native clip

Error message

source binding has no native clip

What it means

Raised by _binding when the referenced track is absent from the validated snapshot's timeline_readback, or the clip_index equals or exceeds the number of clips on that track. The binding must point at a real, existing native clip.

Solutions

  1. Ensure the binding's track exists in snapshot['timeline_readback'] and that clip_index < len(tracks[track]).
  2. Regenerate bindings from the current snapshot instead of reusing stale ones after timeline edits.
  3. Subtract 1 if your source data uses 1-based clip numbering before setting clip_index.

Example fix

// before
{'track': 'video1', 'clip_index': 2}  # video1 has 2 clips (0,1)
// after
{'track': 'video1', 'clip_index': 1}
Defensive patterns

Strategy: validation

Validate before calling

tracks = snapshot['timeline_readback']
for item in bindings:
    assert item['track'] in tracks, f"unknown track {item['track']}"
    assert 0 <= item['clip_index'] < len(tracks[item['track']]), f"clip_index out of range on {item['track']}"

Type guard

def binding_targets_existing_clip(item, tracks) -> bool:
    return item['track'] in tracks and 0 <= item['clip_index'] < len(tracks[item['track']])

Try / catch

try:
    bundle = build_application_bundle(...)
except ValueError as e:
    if 'source binding has no native clip' in str(e):
        log.error('stale binding', bindings=bindings, tracks={k: len(v) for k, v in snapshot['timeline_readback'].items()})
    raise

Prevention

When it happens

Trigger: A binding item with track='video3' when the snapshot only defines video1/video2, or track='video1' with clip_index=2 when video1 has only 2 clips (indices 0 and 1).

Common situations: Timeline was shortened or re-exported and clip indices shifted; bindings cached from an older snapshot; off-by-one when building clip_index from 1-based UI data.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/532fa2059ad1dba4. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/integration.py:246

        raise ValueError("native snapshot clip is incomplete")
    _range([clip["start"], clip["end"]], bounds)
    _integer(clip["left_offset"])
    _integer(clip["right_offset"])
    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

View on GitHub (pinned to 8321021c54)