{"record":{"id":"0468c48f33e9b1bd","repo":"affaan-m/ECC","slug":"source-reference-must-be-https-without-embedded-credentials","errorCode":null,"errorMessage":"source reference must be HTTPS without embedded credentials","messagePattern":"source reference must be HTTPS without embedded credentials","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":352,"sourceCode":"            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\"]):\n        raise ValueError(\"local-only preservation cannot contain candidates or inserts\")\n    tracks = _snapshot(cfg[\"baseline\"])\n    _binding(cfg[\"source\"], tracks, cfg[\"baseline\"])\n    audio_keys = [_binding(item, tracks, cfg[\"baseline\"], audio=True) for item in cfg[\"audio\"]]\n    expected_audio = {(t, i) for t, clips in tracks.items() if t.startswith(\"audio\")\n                      for i in range(len(clips))}\n    if len(set(audio_keys)) != len(audio_keys) or set(audio_keys) != expected_audio:\n        raise ValueError(\"every original audio clip must be preserved exactly once\")\n    stack = _preserved_stack(cfg[\"protected_intervals\"], tracks, cfg[\"baseline\"][\"timeline_range\"])\n    input_hash = None if local_only else _digest(compiled_input)\n    edit_hash = _digest({key: cfg[key] for key in _REQUIRED})","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L334-L370","documentation":"In hosted (non-local_only) mode, compiled_input['source_video'] must be an HTTPS URL with a hostname and no embedded userinfo (username/password). This guard ensures the provider source reference is a secure, unambiguous remote URL and that credentials are never smuggled into the bundle.","triggerScenarios":"build_application_bundle(..., local_only=False) where compiled_input['source_video'] is http://, a bare path, an https URL containing user:pass@, or otherwise lacks a hostname.","commonSituations":"Pasting a local file path (file:// or /mnt/...) into source_video; using an old http:// staging URL; embedding an API token in the URL's userinfo to 'make it work'; URL-encoding artifacts leaving an empty hostname.","solutions":["Use a full https:// URL with an explicit hostname: https://cdn.example.com/source.mp4","Remove any user:password@ userinfo from the URL and pass credentials out-of-band","Ensure the scheme is exactly https, not http or file","Verify with urllib.parse.urlsplit before calling: scheme=='https', hostname truthy, username and password None"],"exampleFix":"// before\n{\"source_video\": \"http://user:token@host/video.mp4\"}\n// after\n{\"source_video\": \"https://host/video.mp4\"}","handlingStrategy":"validation","validationCode":"from urllib.parse import urlsplit\ndef source_url_is_safe(u):\n    url = urlsplit(str(u))\n    return url.scheme == \"https\" and bool(url.hostname) and not url.username and not url.password","typeGuard":"def is_https_source(ci):\n    return isinstance(ci, dict) and source_url_is_safe(ci.get(\"source_video\", \"\"))","tryCatchPattern":"try:\n    bundle = build_application_bundle(cfg, ci, local_only=False)\nexcept ValueError as e:\n    if \"HTTPS without embedded credentials\" in str(e):\n        ci[\"source_video\"] = normalize_to_https(ci[\"source_video\"])  # strip userinfo, upgrade scheme\n        bundle = build_application_bundle(cfg, ci, local_only=False)\n    else:\n        raise","preventionTips":["Store only https:// CDN URLs as source references","Never embed tokens in URL userinfo; use headers or env vars","Validate source_video with urlsplit at config-load time","Reject http:// inputs at ingestion, not at bundle time"],"tags":["security","url-validation","https","credentials"],"backgroundTag":"invalid-url-format","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"}