{"record":{"id":"6391f57d2e5de10f","repo":"affaan-m/ECC","slug":"local-only-must-be-an-exact-boolean","errorCode":null,"errorMessage":"local_only must be an exact boolean","messagePattern":"local_only must be an exact boolean","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":341,"sourceCode":"        if (item[\"retime\"] != \"none\" or target[1] - target[0] != source[1] - source[0]\n                or _rate(candidate[\"fps\"]) != _rate(config[\"baseline\"][\"fps\"])):\n            raise ValueError(\"candidate fps/duration/retime ambiguity\")\n        evidence = _artifact(item[\"approval_file\"], parse_json=True)\n        expected = {\"status\": \"approved\", \"candidate_sha256\": candidate[\"media\"][\"sha256\"],\n                    \"source_sha256\": config[\"source\"][\"media\"][\"sha256\"],\n                    \"compiled_input_sha256\": input_hash,\n                    \"edit_context_sha256\": edit_hash,\n                    \"candidate_range\": source, \"timeline_range\": target}\n        if not isinstance(evidence, dict) or any(\n                _canonical(evidence.get(key)) != _canonical(value) for key, value in expected.items()):\n            raise ValueError(\"approval evidence must bind exact source, candidate and placement\")\n        occupied.append(target)\n\n\ndef build_application_bundle(config: dict, compiled_input: dict | None, *, local_only: bool = False) -> dict:\n    \"\"\"Validate resident evidence and return a new deterministic, offline bundle.\"\"\"\n    if type(local_only) is not bool:\n        raise ValueError(\"local_only must be an exact boolean\")\n    _object(config, _REQUIRED, _OPTIONAL)\n    if len(_canonical(config)) > _MAX_JSON:\n        raise ValueError(\"application config exceeds local size limit\")\n    if local_only:\n        if compiled_input is not None:\n            raise ValueError(\"local-only preservation cannot accept provider input\")\n    else:\n        _object(compiled_input, {\"source_video\", \"compiled_prompt\"})\n        url = urlsplit(_text(compiled_input[\"source_video\"]))\n        if url.scheme != \"https\" or not url.hostname or url.username or url.password:\n            raise ValueError(\"source reference must be HTTPS without embedded credentials\")\n        _text(compiled_input[\"compiled_prompt\"])\n    cfg = copy.deepcopy(config)\n    for key in (\"audio\", \"candidates\", \"inserts\", \"historical_receipts\"):\n        cfg.setdefault(key, [])\n        if not isinstance(cfg[key], list):\n            raise ValueError(\"bundle collections must be lists\")\n    if local_only and (cfg[\"candidates\"] or cfg[\"inserts\"]):","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L323-L359","documentation":"build_application_bundle's local_only is a keyword-only flag that must be a strict Python bool (checked with type(...) is not bool, rejecting truthy values like 1 or 'true'). The strict check prevents ambiguous mode switching between local preservation and hosted provider compilation.","triggerScenarios":"Passing local_only=1, 0, 'true', None, or any non-bool to build_application_bundle or callers that forward it (validate_application_bundle reads it from the bundle dict via bundle.get('local_only', False), so a bundle storing local_only: 1 also trips this).","commonSituations":"Deserializing bundles from JSON/YAML where booleans survived as 1/0 or strings; CLI shims forwarding argparse values as strings; JavaScript-generated configs using true/false incorrectly mapped.","solutions":["Pass a real boolean: build_application_bundle(cfg, ci, local_only=True)","Coerce before calling: local_only = bool(value) only after verifying value in (True, False)","Fix the bundle file so 'local_only' is JSON true/false, not 1/0 or \"true\"","In validate_application_bundle inputs, ensure the serialized bundle stores a proper boolean"],"exampleFix":"// before\nbuild_application_bundle(cfg, ci, local_only=\"true\")\n// after\nbuild_application_bundle(cfg, ci, local_only=True)","handlingStrategy":"type-guard","validationCode":"if not isinstance(local_only, bool):\n    raise TypeError(\"local_only must be a strict bool\")","typeGuard":"def is_strict_bool(v):\n    return type(v) is bool","tryCatchPattern":"try:\n    bundle = build_application_bundle(cfg, ci, local_only=local_only)\nexcept ValueError as e:\n    if \"exact boolean\" in str(e):\n        local_only = (str(local_only).lower() == \"true\")\n        bundle = build_application_bundle(cfg, ci, local_only=local_only)\n    else:\n        raise","preventionTips":["Pass literal True/False, never 1/0 or strings","Parse CLI flags with argparse type=bool or explicit mapping","Ensure JSON bundles serialize local_only as true/false","Add a bool type check in config loaders"],"tags":["validation","type-check","boolean"],"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"}