affaan-m/ECC · error · ValueError

native clip state is incomplete

Error message

native clip state is incomplete

What it means

Raised by _check_clip after the required keys exist: it verifies that clip['enabled'] is exactly a bool (type() is bool, so 0/1 fail) and that clip['properties'] is a dict. It enforces correct types on clip state fields.

Solutions

  1. Set clip['enabled'] to a real Python/JSON boolean true or false, not 0/1 or 'true'.
  2. Set clip['properties'] to a dict (even empty {}), not a list or None.
  3. Normalize the snapshot before use: clip['enabled'] = bool(clip['enabled']); clip['properties'] = dict(clip['properties'] or {}).

Example fix

// before
{'enabled': 1, 'properties': [('speed', 1.0)]}
// after
{'enabled': True, 'properties': {'speed': 1.0}}
Defensive patterns

Strategy: type-guard

Validate before calling

for t, clips in snapshot['timeline_readback'].items():
    for clip in clips:
        assert type(clip['enabled']) is bool, f"{t}: enabled not bool"
        assert isinstance(clip['properties'], dict), f"{t}: properties not dict"

Type guard

def has_valid_clip_state(clip) -> bool:
    return type(clip.get('enabled')) is bool and isinstance(clip.get('properties'), dict)

Try / catch

try:
    bundle = build_application_bundle(...)
except ValueError as e:
    if 'native clip state is incomplete' in str(e):
        # coerce then retry once
        for clips in snapshot['timeline_readback'].values():
            for c in clips:
                c['enabled'] = bool(c['enabled'])
                c['properties'] = dict(c['properties'] or {})
    raise

Prevention

When it happens

Trigger: A clip whose 'enabled' is 0/1, an int, a string like 'true', or None; or whose 'properties' is a list, None, or a missing-but-None value that is not a dict.

Common situations: Snapshots exported from systems where booleans serialize as ints; clip properties accumulated as a list of key/value tuples; YAML/JSON round-trips converting True to 1.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

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

        if not re.fullmatch(r"(?:video|audio)[1-9][0-9]*", track) or not isinstance(clips, list):
            raise ValueError("invalid native snapshot track")
        for clip in clips:
            _check_clip(clip, bounds)
    return tracks


def _check_clip(clip: Any, bounds: list[int]) -> None:
    required = {"path", "name", "start", "end", "left_offset", "right_offset", "enabled", "properties"}
    if not isinstance(clip, dict) or not required <= clip.keys():
        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)

View on GitHub (pinned to 8321021c54)