{"record":{"id":"7583941916ebafcc","repo":"mlflow/mlflow","slug":"unknown-parameter-search-model-type-type-param-se","errorCode":null,"errorMessage":"Unknown parameter search model type {type(param_search_model)}.","messagePattern":"Unknown parameter search model type (.+?)\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"mlflow/pyspark/ml/__init__.py","lineNumber":513,"sourceCode":"    - For TrainValidationSplitModel, the result dict contains metrics for each param map.\n\n    `best_index` is the best index of trials.\n    \"\"\"\n    from pyspark.ml.tuning import CrossValidatorModel, TrainValidationSplitModel\n\n    metrics_dict = {}\n\n    metric_key = param_search_estimator.getEvaluator().getMetricName()\n    if isinstance(param_search_model, CrossValidatorModel):\n        avg_metrics = param_search_model.avgMetrics\n        metrics_dict[\"avg_\" + metric_key] = avg_metrics\n        if hasattr(param_search_model, \"stdMetrics\"):\n            metrics_dict[\"std_\" + metric_key] = param_search_model.stdMetrics\n    elif isinstance(param_search_model, TrainValidationSplitModel):\n        avg_metrics = param_search_model.validationMetrics\n        metrics_dict[metric_key] = avg_metrics\n    else:\n        raise RuntimeError(f\"Unknown parameter search model type {type(param_search_model)}.\")\n\n    if param_search_estimator.getEvaluator().isLargerBetter():\n        best_index = np.argmax(avg_metrics)\n    else:\n        best_index = np.argmin(avg_metrics)\n\n    return metrics_dict, best_index\n\n\ndef _log_estimator_params(param_map):\n    # Chunk model parameters to avoid hitting the log_batch API limit\n    for chunk in _chunk_dict(param_map, chunk_size=MAX_PARAMS_TAGS_PER_BATCH):\n        truncated = _truncate_dict(chunk, MAX_ENTITY_KEY_LENGTH, MAX_PARAM_VAL_LENGTH)\n        mlflow.log_params(truncated)\n\n\nclass _AutologgingMetricsManager:\n    \"\"\"","sourceCodeStart":495,"sourceCodeEnd":531,"githubUrl":"https://github.com/mlflow/mlflow/blob/6a27f2decc0b76eb1b54af31849784addb357dbc/mlflow/pyspark/ml/__init__.py#L495-L531","documentation":"MLflow's PySpark autologging extracts validation metrics from parameter-search results, supporting CrossValidatorModel and TrainValidationSplitModel. If the fitted model is neither of these types, MLflow cannot find validationMetrics and raises this RuntimeError.","triggerScenarios":"Passing a fitted model to _log_posttraining_metadata / _create_child_runs_for_parameter_search that is not a CrossValidatorModel or TrainValidationSplitModel, e.g. a custom tuner, a wrapped model, or a tune step whose result was unwrapped to the best model.","commonSituations":"Autologging custom hyperparameter-tuning wrappers; calling .bestModel and logging the result as if it were the tuner model; Spark version changes introducing new tuner classes not yet supported.","solutions":["Log the CrossValidatorModel/TrainValidationSplitModel itself, not its .bestModel.","Confirm the tuning estimator is pyspark.ml.tuning.CrossValidator or TrainValidationSplit.","Unwrap any custom tuner to the underlying Spark model before autolog logging.","Upgrade MLflow if a newer Spark tuner type is the cause."],"exampleFix":"# before\nbest = cv_model.bestModel\nmlflow.pyspark.ml.log_posttraining_metadata(...)  # expects tuner model, got best estimator\n# after\nmlflow.pyspark.ml.log_posttraining_metadata(...)  # pass cv_model (the tuner model)","handlingStrategy":"type-guard","validationCode":"from pyspark.ml.tuning import CrossValidatorModel, TrainValidationSplitModel\nif not isinstance(tuner_model, (CrossValidatorModel, TrainValidationSplitModel)):\n    raise TypeError(f\"Expected tuner model, got {type(tuner_model)}\")","typeGuard":"from pyspark.ml.tuning import CrossValidatorModel, TrainValidationSplitModel\ndef is_param_search_model(m) -> bool:\n    return isinstance(m, (CrossValidatorModel, TrainValidationSplitModel))","tryCatchPattern":"try:\n    log_tuning_metadata(model)\nexcept RuntimeError as e:\n    if \"Unknown parameter search model type\" in str(e):\n        log_tuning_metadata(model._original_tuner_model)","preventionTips":["Log the CrossValidatorModel/TrainValidationSplitModel, not .bestModel","Avoid custom tuner wrappers with autologging","Check MLflow/Spark version compatibility for new tuner classes"],"tags":["pyspark","autologging","tuning","unsupported-type"],"backgroundTag":"unsupported-type","analyzedSha":"6a27f2decc0b76eb1b54af31849784addb357dbc","analyzedAt":"2026-08-29T20:54:51.419Z","schemaVersion":2},"datasetVersion":"2026-08-29T22:17:34.462Z"}