{"record":{"id":"c71b07d49e6423b9","repo":"affaan-m/ECC","slug":"wrong-source-audio-track-kind","errorCode":null,"errorMessage":"wrong source/audio track kind","messagePattern":"wrong source/audio track kind","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":244,"sourceCode":"    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\")\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","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L226-L262","documentation":"Raised by _binding when the track string of a source binding item does not start with 'audio' when audio=True, or 'video' when audio=False. Each binding must reference a track of the expected kind matching the media type being applied.","triggerScenarios":"Calling build_application_bundle with a binding item whose 'track' is 'video1' but is being processed as an audio binding (or vice versa), e.g. an audio media element bound to a video track.","commonSituations":"Swapped audio/video flags in the caller's data model; templates that place audio elements on video tracks; copy-pasted binding dicts where only 'track' was edited but the media kind wasn't.","solutions":["Make the binding's 'track' kind match the media type: audio media must use 'audio<n>' tracks, video media must use 'video<n>' tracks.","Verify the audio flag/element type feeding _binding is correct for the item being bound.","Fix the template or generated bindings so track prefixes agree with the element's media kind."],"exampleFix":"// before\n{'media': audio_media, 'track': 'video1', ...}\n// after\n{'media': audio_media, 'track': 'audio1', ...}","handlingStrategy":"validation","validationCode":"for item in bindings:\n    expected = 'audio' if item['media']['kind'] == 'audio' else 'video'\n    assert item['track'].startswith(expected), f\"track kind mismatch: {item['track']}\"","typeGuard":"def track_kind_matches(item, audio: bool) -> bool:\n    t = item.get('track')\n    return isinstance(t, str) and t.startswith('audio' if audio else 'video')","tryCatchPattern":"try:\n    bundle = build_application_bundle(...)\nexcept ValueError as e:\n    if 'wrong source/audio track kind' in str(e):\n        for item in bindings:\n            log.error('kind mismatch', track=item['track'], media=item['media'])\n    raise","preventionTips":["Derive track names from the media element's kind, never hardcode them","Keep audio elements on audio tracks in templates","Add a pre-flight check pairing media kind with track prefix"],"tags":["validation","binding","media"],"backgroundTag":"invalid-argument-value","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"}