{"record":{"id":"a0f26d2e5cdd24b6","repo":"unslothai/unsloth","slug":"learning-rate-must-be-a-number-got-self-learning","errorCode":null,"errorMessage":"learning_rate must be a number, got {self.learning_rate!r}","messagePattern":"learning_rate must be a number, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"studio/backend/core/training/diffusion_train_common.py","lineNumber":1177,"sourceCode":"                    \"flow_shift must be a finite number > 0 (1.0 disables the shift), or 'auto'\"\n                )\n        try:\n            cfg_dropout = float(self.cfg_dropout or 0.0)\n        except (TypeError, ValueError) as exc:\n            raise ValueError(f\"cfg_dropout must be a number, got {self.cfg_dropout!r}\") from exc\n        if not 0.0 <= cfg_dropout <= 1.0:\n            raise ValueError(\"cfg_dropout must be between 0 and 1\")\n        weighting_scheme = str(self.weighting_scheme or \"none\").strip().lower()\n        if weighting_scheme not in (\"none\", \"bell\"):\n            raise ValueError(\"weighting_scheme must be one of none / bell\")\n        # A zero/negative gamma would zero out (or invert) the min-SNR weight and silently train on a degenerate loss; None is the documented disable.\n        if self.snr_gamma is not None and float(self.snr_gamma) <= 0:\n            raise ValueError(\"snr_gamma must be > 0, or null to disable min-SNR weighting\")\n        # learning_rate can arrive as a string (\"1e-4\") from the Studio config path, so coerce it before AdamW sees it.\n        try:\n            learning_rate = float(self.learning_rate)\n        except (TypeError, ValueError) as exc:\n            raise ValueError(f\"learning_rate must be a number, got {self.learning_rate!r}\") from exc\n        if learning_rate <= 0:\n            raise ValueError(\"learning_rate must be > 0\")\n        alpha = self.lora_alpha if self.lora_alpha is not None else self.lora_rank\n        targets = tuple(self.lora_target_modules) or DEFAULT_LORA_TARGETS\n        # A blank Hub token (the Studio default when none is configured) must load anonymously, not as an explicit empty credential.\n        token = self.hf_token.strip() if isinstance(self.hf_token, str) else self.hf_token\n        from core.inference.diffusion_families import (\n            _is_local_path,\n            mirror_repo,\n            prefer_ungated_mirror,\n            upstream_is_gated,\n        )\n\n        if resolved_family == \"sdxl\":\n            fetch_base_model = self.base_model\n        else:\n            fetch_base_model = prefer_ungated_mirror(self.base_model, token or None)\n            # For a GATED upstream and no token, the cache preference has to be overridden: the","sourceCodeStart":1159,"sourceCodeEnd":1195,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/training/diffusion_train_common.py#L1159-L1195","documentation":"learning_rate is coerced with float() because the Studio config path can deliver it as a string ('1e-4'). If the value is not numeric and not a numeric string, the coercion raises TypeError/ValueError and the config re-raises with the original value echoed.","triggerScenarios":"learning_rate='lr', '1e-4x', a list, or None handled incorrectly at the call site (None raises TypeError here, unlike cfg_dropout's 'or' fallback).","commonSituations":"Hand-edited YAML/JSON with a typo; a UI field left with placeholder text like 'e.g. 0.0001'; unit-suffixed strings like '4e-5lr'.","solutions":["Pass a plain number (0.0001) or a clean numeric string ('1e-4').","Sanitize free-text input: strip whitespace and reject anything float() cannot parse before it reaches the config.","Check for stray characters pasted alongside the value (units, commas, currency symbols)."],"exampleFix":"# before\ncfg = DiffusionLoraConfig(learning_rate='0.0001 ')  # ok, but '1e-4 lr' fails\n# after\ncfg = DiffusionLoraConfig(learning_rate='1e-4')  # or 0.0001","handlingStrategy":"validation","validationCode":"def coerce_lr(v):\n    if isinstance(v, str):\n        v = v.strip().replace(',', '')  # tolerate '1e-4 ' / '0,0001'\n    lr = float(v)\n    if lr <= 0:\n        raise ValueError('learning_rate must be > 0')\n    return lr","typeGuard":"def is_valid_learning_rate(v) -> bool:\n    try:\n        return float(v) > 0\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":null,"preventionTips":["Treat learning_rate as a required numeric field in forms; reject placeholder text at submission.","Run float() coercion in your config loader so bad values fail with your own error message."],"tags":["training","config","hyperparameters","validation"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}