{"record":{"id":"1d967396c316b7a5","repo":"mudler/LocalAI","slug":"model-snapshot-must-contain-exactly-one-suffix-f","errorCode":null,"errorMessage":"model snapshot must contain exactly one {suffix} file; found {len(matches)}","messagePattern":"model snapshot must contain exactly one (.+?) file; found (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/python/common/model_utils.py","lineNumber":25,"sourceCode":"        return model_file, True\n    model = (getattr(request, \"Model\", \"\") or \"\").strip()\n    return model or default, False\n\n\ndef require_snapshot_file(model_ref, suffix):\n    if os.path.isfile(model_ref) and model_ref.endswith(suffix):\n        return model_ref\n    if not os.path.isdir(model_ref):\n        raise ValueError(f\"model snapshot does not exist: {model_ref}\")\n\n    matches = []\n    for root, directories, files in os.walk(model_ref):\n        directories.sort()\n        for name in sorted(files):\n            if name.endswith(suffix):\n                matches.append(os.path.join(root, name))\n    if len(matches) != 1:\n        raise ValueError(\n            f\"model snapshot must contain exactly one {suffix} file; found {len(matches)}\"\n        )\n    return matches[0]\n","sourceCodeStart":7,"sourceCodeEnd":29,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/python/common/model_utils.py#L7-L29","documentation":"Thrown by require_snapshot_file after walking the snapshot directory when the count of files ending with the expected suffix is not exactly one. The loader requires an unambiguous artifact: zero matches means the snapshot is incomplete, two or more means it cannot choose safely.","triggerScenarios":"os.walk over the model_ref directory finds 0 files with the suffix (incomplete download, wrong snapshot layout) or finds 2+ (multiple variants dumped in one directory, e.g. both a quantized and full model file).","commonSituations":"An interrupted model download that left a partial snapshot, a user manually copying several model variants into one folder, or a gallery pack that ships more than one file of the same type (e.g. two .onnx or two .safetensors).","solutions":["List files under the snapshot directory (find <dir> -name '*<suffix>') to see whether the problem is zero or multiple matches.","If multiple: keep exactly one intended file and delete/move the others, or point request.ModelFile directly at the file you want (the direct-file branch bypasses the walk).","If zero: re-download/reinstall the model snapshot; the download was likely truncated or the layout changed upstream.","For pack layouts with legitimately several variants, split them into per-variant snapshot directories."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import os\nmatches = [os.path.join(r, f) for r, d, fs in os.walk(model_ref) for f in fs if f.endswith(suffix)]\nassert len(matches) == 1, f\"expected exactly 1 {suffix} file, found {len(matches)}: {matches}\"","typeGuard":null,"tryCatchPattern":"try:\n    model_file = require_snapshot_file(model_ref, \".safetensors\")\nexcept ValueError as e:\n    if \"exactly one\" in str(e):\n        # ambiguous snapshot: surface choices to user instead of failing silently\n        raise\n    raise","preventionTips":["Keep one variant per snapshot directory; separate quantizations into their own folders.","Verify downloads completed (checksum/file count) before serving a snapshot.","When multiple variants are legitimate, address the file directly via ModelFile."],"tags":["model-loading","snapshot-validation","localai","configuration"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}