{"record":{"id":"77eda7547dfc468e","repo":"affaan-m/ECC","slug":"native-snapshot-clip-is-incomplete","errorCode":null,"errorMessage":"native snapshot clip is incomplete","messagePattern":"native snapshot clip is incomplete","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":228,"sourceCode":"        raise ValueError(\"native snapshot fps is missing, invalid or contradictory\") from exc\n    for cfg, key in [(\"project_name\", \"project\"), (\"timeline_name\", \"timeline\")]:\n        if _text(baseline[cfg]) != snapshot.get(key):\n            raise ValueError(\"native snapshot identity mismatch\")\n    tracks = snapshot.get(\"timeline_readback\")\n    if not isinstance(tracks, dict) or not tracks:\n        raise ValueError(\"native clip snapshot required\")\n    for track, clips in tracks.items():\n        if not re.fullmatch(r\"(?:video|audio)[1-9][0-9]*\", track) or not isinstance(clips, list):\n            raise ValueError(\"invalid native snapshot track\")\n        for clip in clips:\n            _check_clip(clip, bounds)\n    return tracks\n\n\ndef _check_clip(clip: Any, bounds: list[int]) -> None:\n    required = {\"path\", \"name\", \"start\", \"end\", \"left_offset\", \"right_offset\", \"enabled\", \"properties\"}\n    if not isinstance(clip, dict) or not required <= clip.keys():\n        raise ValueError(\"native snapshot clip is incomplete\")\n    _range([clip[\"start\"], clip[\"end\"]], bounds)\n    _integer(clip[\"left_offset\"])\n    _integer(clip[\"right_offset\"])\n    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\")","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L210-L246","documentation":"Raised by _check_clip when a clip in a native snapshot track is not a dict or is missing any of the required keys: path, name, start, end, left_offset, right_offset, enabled, properties. The validator requires a complete clip schema before range/offset checks run.","triggerScenarios":"build_application_bundle -> _snapshot -> _check_clip encounters a clip entry lacking one or more of the eight required keys, or the entry is not a dict (e.g. a path string or None).","commonSituations":"Snapshots assembled by hand or by an older exporter that omits 'properties' or 'left_offset'/'right_offset'; JSON snapshots where clips lost fields after a schema change; a clip entry accidentally reduced to just its path.","solutions":["Add all missing required keys (path, name, start, end, left_offset, right_offset, enabled, properties) to each clip dict.","Check clip keys against `required = {\"path\",\"name\",\"start\",\"end\",\"left_offset\",\"right_offset\",\"enabled\",\"properties\"}` before calling the API.","Regenerate the snapshot with the current native exporter version instead of reusing an old one."],"exampleFix":"// before\n{'path': 'a.mp4', 'start': 0, 'end': 100}\n// after\n{'path': 'a.mp4', 'name': 'a', 'start': 0, 'end': 100, 'left_offset': 0, 'right_offset': 0, 'enabled': True, 'properties': {}}","handlingStrategy":"validation","validationCode":"required = {'path','name','start','end','left_offset','right_offset','enabled','properties'}\nfor track, clips in snapshot['timeline_readback'].items():\n    for i, clip in enumerate(clips):\n        missing = required - set(clip.keys())\n        assert isinstance(clip, dict) and not missing, f'{track}[{i}] missing {missing}'","typeGuard":"def is_complete_clip(clip) -> bool:\n    required = {'path','name','start','end','left_offset','right_offset','enabled','properties'}\n    return isinstance(clip, dict) and required <= clip.keys()","tryCatchPattern":"try:\n    bundle = build_application_bundle(...)\nexcept ValueError as e:\n    if 'native snapshot clip is incomplete' in str(e):\n        for t, clips in snapshot['timeline_readback'].items():\n            for i, c in enumerate(clips):\n                if not isinstance(c, dict) or not required <= c.keys():\n                    log.error('incomplete clip', track=t, index=i, keys=sorted(c.keys()) if isinstance(c, dict) else None)\n    raise","preventionTips":["Keep snapshot producers and consumers on the same schema version","Diff clip keys against the required set in CI tests","Never trim clip dicts when copying them between systems"],"tags":["validation","snapshot","schema"],"backgroundTag":"schema-validation-failed","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"}