diff --git a/src/dstack/_internal/core/models/configurations.py b/src/dstack/_internal/core/models/configurations.py index ac8d8d172..d81cdecee 100644 --- a/src/dstack/_internal/core/models/configurations.py +++ b/src/dstack/_internal/core/models/configurations.py @@ -987,7 +987,7 @@ def validate_scaling(cls, values): @root_validator() def validate_top_level_properties_with_replica_groups(cls, values): """ - When replicas is a list of ReplicaGroup, forbid top-level scaling, commands, and resources + When replicas is a list of ReplicaGroup, forbid top-level scaling and commands. """ replicas = values.get("replicas") @@ -1008,15 +1008,6 @@ def validate_top_level_properties_with_replica_groups(cls, values): "Specify `commands` in each replica group instead." ) - resources = values.get("resources") - - default_resources = ResourcesSpec() - if resources and resources.dict() != default_resources.dict(): - raise ValueError( - "Top-level `resources` is not allowed when `replicas` is a list. " - "Specify `resources` in each replica group instead." - ) - return values @root_validator() diff --git a/src/dstack/_internal/server/services/runs/spec.py b/src/dstack/_internal/server/services/runs/spec.py index 8623fd0a1..3a611073d 100644 --- a/src/dstack/_internal/server/services/runs/spec.py +++ b/src/dstack/_internal/server/services/runs/spec.py @@ -5,6 +5,7 @@ ServiceConfiguration, ) from dstack._internal.core.models.repos.virtual import DEFAULT_VIRTUAL_REPO_ID, VirtualRunRepoData +from dstack._internal.core.models.resources import ResourcesSpec from dstack._internal.core.models.runs import LEGACY_REPO_DIR, AnyRunConfiguration, RunSpec from dstack._internal.core.models.volumes import InstanceMountPoint from dstack._internal.core.services import validate_dstack_resource_name @@ -112,6 +113,16 @@ def validate_run_spec_and_set_defaults( raise ServerClientError( f"Probe timeout cannot be longer than {settings.MAX_PROBE_TIMEOUT}s" ) + if isinstance(run_spec.configuration.replicas, list): + default_resources = ResourcesSpec() + if ( + run_spec.configuration.resources + and run_spec.configuration.resources.dict() != default_resources.dict() + ): + raise ServerClientError( + "Top-level `resources` is not allowed when `replicas` is a list. " + "Specify `resources` in each replica group instead." + ) if run_spec.configuration.priority is None: run_spec.configuration.priority = RUN_PRIORITY_DEFAULT set_resources_defaults(run_spec.configuration.resources)