{"record":{"id":"0e79237ed5a8bcb1","repo":"mudler/LocalAI","slug":"unknown-backend-backend","errorCode":null,"errorMessage":"Unknown backend: {backend}","messagePattern":"Unknown backend: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/python/mlx-distributed/backend.py","lineNumber":66,"sourceCode":"    JACCL: MLX_IBV_DEVICES points to a JSON 2D matrix of RDMA device names.\n    MLX_JACCL_COORDINATOR is rank 0's ip:port where it runs a TCP service that\n    helps all ranks establish RDMA connections.\n    \"\"\"\n    import mlx.core as mx\n\n    if backend == \"ring\":\n        os.environ[\"MLX_HOSTFILE\"] = hostfile\n        os.environ[\"MLX_RANK\"] = str(rank)\n        os.environ[\"MLX_RING_VERBOSE\"] = \"1\"\n        return mx.distributed.init(backend=\"ring\", strict=True)\n    elif backend == \"jaccl\":\n        os.environ[\"MLX_IBV_DEVICES\"] = hostfile\n        os.environ[\"MLX_RANK\"] = str(rank)\n        if coordinator:\n            os.environ[\"MLX_JACCL_COORDINATOR\"] = coordinator\n        return mx.distributed.init(backend=\"jaccl\", strict=True)\n    else:\n        raise ValueError(f\"Unknown backend: {backend}\")\n\n\n# Re-export the shared helper under the local name for back-compat with\n# any callers (and the existing distributed worker tests) that imported\n# parse_options directly from this module.\nparse_options = _shared_parse_options\n\n\nclass BackendServicer(backend_pb2_grpc.BackendServicer):\n    \"\"\"gRPC servicer for distributed MLX inference (runs on rank 0).\n\n    When started by LocalAI (server mode), distributed init happens at\n    LoadModel time using config from model options or environment variables.\n    \"\"\"\n\n    def __init__(self):\n        self.group = None\n        self.dist_backend = None","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/python/mlx-distributed/backend.py#L48-L84","documentation":"Raised by the distributed-init helper in the mlx-distributed backend when the backend string is neither 'ring' nor 'jaccl'. Only those two MLX distributed backends are wired up; anything else falls to the else branch and raises immediately.","triggerScenarios":"Calling the init function with backend='nccl', 'gloo', or a typo like 'Ring'/'JACCL' (case-sensitive). Values typically come from CLI options or the model config's distributed section.","commonSituations":"Porting configs from PyTorch distributed setups that use nccl/gloo, case mismatches, or referencing a backend removed/renamed between MLX versions.","solutions":["Use exactly 'ring' or 'jaccl'","Check case and whitespace in the config value (strip() it)","For MPI-style clusters use 'ring' with a hostfile; for IB/ROCm clusters use 'jaccl'"],"exampleFix":"# before\ninit_distributed('NCCL', hostfile, rank)  # ValueError\n\n# after\ninit_distributed('ring', hostfile, rank)","handlingStrategy":"type-guard","validationCode":"VALID = {'ring', 'jaccl'}\nbackend = (cfg.get('distributed', {}).get('backend') or 'ring').strip().lower()\nif backend not in VALID:\n    raise ValueError(f'backend must be one of {sorted(VALID)}, got {backend!r}')","typeGuard":"def is_known_backend(name) -> bool:\n    return isinstance(name, str) and name.strip().lower() in {'ring', 'jaccl'}","tryCatchPattern":"try:\n    init_distributed(backend, hostfile, rank)\nexcept ValueError as err:\n    sys.exit(f'config error: {err}')  # fail fast, no fallback","preventionTips":["Normalize case/whitespace on config values","Only ring/jaccl exist — never assume nccl/gloo","Validate config in a preflight check before spawning workers"],"tags":["python","mlx","distributed","validation"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}