{"record":{"id":"b87cc6dc4e3b985c","repo":"affaan-m/ECC","slug":"label-has-an-invalid-finite-source-duration","errorCode":null,"errorMessage":"{label} has an invalid finite source duration","messagePattern":"(.+?) has an invalid finite source duration","errorType":"validation","errorClass":"ContractError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/contract.py","lineNumber":28,"sourceCode":"import stat\nfrom pathlib import Path\nfrom typing import Any, cast\n\n_REQUIRED_MODALITIES = {\"image\", \"video\", \"3d_asset\"}\n_SIGNATURE_AXES = {\"materials\", \"motion\", \"composition\", \"avoid\"}\n\n\nclass ContractError(ValueError):\n    \"\"\"The dry-run bundle is incomplete or has lost taste specificity.\"\"\"\n\n\ndef _is_finite_real(value: Any) -> bool:\n    return isinstance(value, (int, float)) and not isinstance(value, bool) and math.isfinite(value)\n\n\ndef _validate_media_time(value: Any, source_duration: Any, *, label: str) -> None:\n    if not _is_finite_real(source_duration):\n        raise ContractError(f\"{label} has an invalid finite source duration\")\n    source_duration = cast(float, source_duration)\n    if float(source_duration) <= 0:\n        raise ContractError(f\"{label} has an invalid finite source duration\")\n    if (not _is_finite_real(value) or float(value) < 0\n            or float(value) > float(source_duration)):\n        raise ContractError(f\"{label} is outside its source duration\")\n\n\ndef _validate_numeric_evidence(value: Any, *, label: str) -> None:\n    if isinstance(value, bool):\n        raise ContractError(f\"{label} contains a boolean numeric value\")\n    if isinstance(value, (int, float)):\n        if not math.isfinite(value):\n            raise ContractError(f\"{label} contains a non-finite numeric value\")\n    elif isinstance(value, dict):\n        for nested in value.values():\n            _validate_numeric_evidence(nested, label=label)\n    elif isinstance(value, list):","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/contract.py#L10-L46","documentation":"_validate_media_time requires the source_duration argument to be a finite, non-boolean real number before validating a media time value against it. The first check raises when source_duration is not a finite int/float (None, string, bool, NaN, inf). This ensures all later numeric comparisons are well-defined.","triggerScenarios":"Calling any validator (validate_genre_specs, validate_effect_recipe, validate_provenance, validate_artifact_receipt, _validate_probe_evidence) with a source_duration of null, a numeric string like \"12.5\", True, NaN, or Infinity.","commonSituations":"Probe JSON where the duration field was omitted or left as a string, NaN/Infinity produced by upstream ffmpeg/ffprobe parsing, or bools slipping in from YAML's yes/no mapping to true/false.","solutions":["Ensure the source JSON carries duration as a JSON number, not a string; convert with float() at authoring time.","Handle None/missing duration by fixing the upstream document before calling the validator.","Reject non-finite floats (NaN/Inf) when loading the document; they indicate corrupt probe data.","Sanitize bools out of numeric fields (isinstance(v, bool) check) before validation."],"exampleFix":"// before\ndoc['duration'] = str(ffprobe_seconds)  # \"12.5\"\n// after\ndoc['duration'] = float(ffprobe_seconds)  # 12.5","handlingStrategy":"type-guard","validationCode":"import math\ndef valid_source_duration(v) -> bool:\n    return isinstance(v, (int, float)) and not isinstance(v, bool) and math.isfinite(v)","typeGuard":"def is_finite_real(v) -> bool:\n    return isinstance(v, (int, float)) and not isinstance(v, bool) and math.isfinite(v)","tryCatchPattern":"try:\n    validate_genre_specs(spec, source_duration=dur)\nexcept ContractError as e:\n    if 'invalid finite source duration' in str(e):\n        dur = float(probe['duration'])  # repair from probe\n    else:\n        raise","preventionTips":["Store durations as JSON numbers, never strings","Reject NaN/Infinity at document load time","Exclude bools from numeric fields (isinstance(v, bool) check)","Run ffprobe results through a numeric sanitizer before writing manifests"],"tags":["python","validation","numeric"],"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"}