{"record":{"id":"1f786f6f3e9c0089","repo":"mudler/LocalAI","slug":"unsupported-training-method-training-method-su","errorCode":null,"errorMessage":"Unsupported training method: {training_method}. Supported: sft, dpo, grpo, orpo, kto, rloo, reward","messagePattern":"Unsupported training method: (.+?)\\. Supported: sft, dpo, grpo, orpo, kto, rloo, reward","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/python/trl/backend.py","lineNumber":596,"sourceCode":"\n            max_length = int(extra.get(\"max_length\", \"512\"))\n\n            training_args = RewardConfig(\n                max_length=max_length,\n                **_common_args,\n            )\n\n            trainer = RewardTrainer(\n                model=model,\n                args=training_args,\n                train_dataset=dataset,\n                eval_dataset=eval_dataset,\n                processing_class=tokenizer,\n                callbacks=[progress_cb.get_callback()],\n            )\n\n        else:\n            raise ValueError(f\"Unsupported training method: {training_method}. \"\n                             \"Supported: sft, dpo, grpo, orpo, kto, rloo, reward\")\n\n        job.trainer = trainer\n\n        # Start training\n        job.progress_queue.put(backend_pb2.FineTuneProgressUpdate(\n            job_id=job.job_id, status=\"training\", message=\"Training started\",\n        ))\n\n        resume_ckpt = request.resume_from_checkpoint if request.resume_from_checkpoint else None\n        trainer.train(resume_from_checkpoint=resume_ckpt)\n\n        # Save final model\n        trainer.save_model(output_dir)\n        if tokenizer:\n            tokenizer.save_pretrained(output_dir)\n\n        job.completed = True","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/python/trl/backend.py#L578-L614","documentation":"The TRL backend dispatches on request.training_method to construct a matching Trainer subclass (SFT/DPO/GRPO/ORPO/KTO/RLOO/Reward). Any other string falls into the else branch and raises ValueError with the supported list, so typos and unsupported methods fail fast before model loading.","triggerScenarios":"training_method='SFT ' (trailing whitespace) or 'Dpo' (case mismatch) depending on how the method is normalized; training_method='pretrain' or 'rlhf'; an unset field defaulting to an unexpected value.","commonSituations":"Client sends free-text method names; version skew where a newer client uses a method this backend build does not know; locale/case differences.","solutions":["Set training_method to one of: sft, dpo, grpo, orpo, kto, rloo, reward (lowercase).","Trim/normalize whitespace and casing on the client before sending.","If you need a newer method, upgrade the TRL backend image to a build that supports it."],"exampleFix":"# before\nrequest.training_method = \"DPO \"\n# after\nrequest.training_method = \"dpo\"","handlingStrategy":"validation","validationCode":"SUPPORTED = {\"sft\", \"dpo\", \"grpo\", \"orpo\", \"kto\", \"rloo\", \"reward\"}\n\ndef method_ok(method: str) -> bool:\n    return (method or \"\").strip().lower() in SUPPORTED","typeGuard":"def is_supported_method(m: str) -> bool:\n    SUPPORTED = {\"sft\", \"dpo\", \"grpo\", \"orpo\", \"kto\", \"rloo\", \"reward\"}\n    return isinstance(m, str) and m.strip().lower() in SUPPORTED","tryCatchPattern":"try:\n    dispatch(request)\nexcept ValueError as e:\n    if \"Unsupported training method\" in str(e):\n        return client_error(400, str(e))\n    raise","preventionTips":["Normalize training_method with .strip().lower() at the API boundary.","Expose the supported list to clients via a capabilities endpoint.","Validate with an enum in client SDKs."],"tags":["trl","fine-tuning","validation","enum","localai"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}