{"record":{"id":"a04ecea03c62394d","repo":"Unity-Technologies/ml-agents","slug":"binary-not-found-make-sure-url-is-a-valid-url-t","errorCode":null,"errorMessage":"Binary not found, make sure {url} is a valid url to a zip folder containing a valid Unity executable","messagePattern":"Binary not found, make sure (.+?) is a valid url to a zip folder containing a valid Unity executable","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"ml-agents-envs/mlagents_envs/registry/binary_utils.py","lineNumber":63,"sourceCode":"        for attempt in range(\n            NUMBER_ATTEMPTS\n        ):  # Perform 5 attempts at downloading the file\n            if path is not None:\n                break\n            try:\n                download_and_extract_zip(url, name, tmp_dir=tmp_dir)\n            except Exception:\n                if attempt + 1 < NUMBER_ATTEMPTS:\n                    logger.warning(\n                        f\"Attempt {attempt + 1} / {NUMBER_ATTEMPTS}\"\n                        \": Failed to download and extract binary.\"\n                    )\n                else:\n                    raise\n            path = get_local_binary_path_if_exists(name, url, tmp_dir=tmp_dir)\n\n    if path is None:\n        raise FileNotFoundError(\n            f\"Binary not found, make sure {url} is a valid url to \"\n            \"a zip folder containing a valid Unity executable\"\n        )\n    return path\n\n\ndef get_local_binary_path_if_exists(name: str, url: str, tmp_dir: str) -> Optional[str]:\n    \"\"\"\n    Recursively searches for a Unity executable in the extracted files folders. This is\n    platform dependent : It will only return a Unity executable compatible with the\n    computer's OS. If no executable is found, None will be returned.\n    :param name: The name/identifier of the executable\n    :param url: The url the executable was downloaded from (for verification)\n    :param: tmp_dir: Optional override for the temporary directory to save binaries and zips in.\n    \"\"\"\n    _, bin_dir = get_tmp_dirs(tmp_dir)\n    extension = None\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents-envs/mlagents_envs/registry/binary_utils.py#L45-L81","documentation":"FileNotFoundError raised by binary_utils.get_local_binary_path when, after attempting download/extraction from the given url, no matching Unity executable binary can be found locally for that (name, url) pair.","triggerScenarios":"Calling a remote registry entry's make() (or get_local_binary_path directly) where the url points to a zip that failed to download, is invalid, has no executable inside, or whose cache directory in tmp_dir lacks a matching binary.","commonSituations":"Dead or moved binary-download URL; network blocked in CI so the zip never downloads; extracted zip uses an unexpected directory layout so the glob for the platform extension finds nothing; disk cache cleared between download and lookup.","solutions":["Verify the url with curl -I; if dead, update the manifest to a valid zip containing the Unity executable.","Download the binary manually and place it in the expected cache path (bin_dir/name-<md5(url)>) or pass tmp_dir pointing at a pre-extracted location.","Check network/proxy settings and retry the download.","Use a local UnityEnvironment(file_name=...) directly instead of the remote registry."],"exampleFix":"// before\nentry = registry['3dball']  # url 404s at runtime\nenv = entry.make()\n// after\nenv = UnityEnvironment(file_name='/path/to/3DBall/UnityEnvironment.x86_64')","handlingStrategy":"try-catch","validationCode":"import os, glob\npath = os.path.join(tmp_dir, \"**\", \"*.x86_64\")  # match platform ext\nif not glob.glob(path, recursive=True) and not os.environ.get(\"MLAGENTS_BINARY\"):\n    raise FileNotFoundError(\"Binary not downloaded yet; pre-fetch or set MLAGENTS_BINARY\")\nenv = entry.make()","typeGuard":"def binary_available(tmp_dir: str, name: str, url: str) -> bool:\n    import hashlib, glob\n    h = \"-\" + hashlib.md5(url.encode()).hexdigest()\n    return len(glob.glob(os.path.join(tmp_dir, name + h, \"**\", \"*\"), recursive=True)) > 0","tryCatchPattern":"try:\n    env = entry.make()\nexcept FileNotFoundError:\n    env = UnityEnvironment(file_name=os.environ[\"LOCAL_UNITY_BINARY\"])","preventionTips":["Pre-download the binary and warm the cache before make()","Validate binary URLs in CI before running training","Fall back to a local UnityEnvironment path"],"tags":["download","file-not-found","registry"],"backgroundTag":"binary-not-found","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}