Repository: archlinux/archinstall

Issue:
Loading saved configs doesn't fully install DEs like GNOME or KDE
* archinstall 2.6.0.

Steps:
* selected all the necessary, Profile > Desktop > KDE or GNOME
* save config to files.
* abort install
* run again with options --config user_configuration.json --creds user_credentials.json

If you run like this you will get only minimal DE install without any GNOME/KDE apps like gnome-control-center, console, tweaks etc. Probably you get only dependecies for greeter.


Discussion:
Thanks for reporting I was able to reproduce this

Resolving patch:
diff --git a/archinstall/lib/profile/profile_model.py b/archinstall/lib/profile/profile_model.py
--- a/archinstall/lib/profile/profile_model.py
+++ b/archinstall/lib/profile/profile_model.py
@@ -27,11 +27,13 @@ def json(self) -> Dict[str, Any]:
 	@classmethod
 	def parse_arg(cls, arg: Dict[str, Any]) -> 'ProfileConfiguration':
 		from .profiles_handler import profile_handler
+
+		profile = profile_handler.parse_profile_config(arg['profile'])
 		greeter = arg.get('greeter', None)
 		gfx_driver = arg.get('gfx_driver', None)
 
 		return ProfileConfiguration(
-			profile_handler.parse_profile_config(arg['profile']),
+			profile,
 			GfxDriver(gfx_driver) if gfx_driver else None,
 			GreeterType(greeter) if greeter else None
 		)
diff --git a/archinstall/lib/profile/profiles_handler.py b/archinstall/lib/profile/profiles_handler.py
--- a/archinstall/lib/profile/profiles_handler.py
+++ b/archinstall/lib/profile/profiles_handler.py
@@ -52,9 +52,9 @@ def to_json(self, profile: Optional[Profile]) -> Dict[str, Any]:
 
 	def parse_profile_config(self, profile_config: Dict[str, Any]) -> Optional[Profile]:
 		"""
-		Deserialize JSON configuration
+		Deserialize JSON configuration for profile
 		"""
-		profile = None
+		profile: Optional[Profile] = None
 
 		# the order of these is important, we want to
 		# load all the default_profiles from url and custom
@@ -97,29 +97,26 @@ def parse_profile_config(self, profile_config: Dict[str, Any]) -> Optional[Profi
 		if main := profile_config.get('main', None):
 			profile = self.get_profile_by_name(main) if main else None
 
-		valid: List[Profile] = []
+		if not profile:
+			return None
+
+		valid_sub_profiles: List[Profile] = []
+		invalid_sub_profiles: List[str] = []
 		details: List[str] = profile_config.get('details', [])
-		if details:
-			valid = []
-			invalid = []
 
+		if details:
 			for detail in filter(None, details):
-				if profile := self.get_profile_by_name(detail):
-					valid.append(profile)
+				if sub_profile := self.get_profile_by_name(detail):
+					valid_sub_profiles.append(sub_profile)
 				else:
-					invalid.append(detail)
+					invalid_sub_profiles.append(detail)
 
-			if invalid:
-				info('No profile definition found: {}'.format(', '.join(invalid)))
+			if invalid_sub_profiles:
+				info('No profile definition found: {}'.format(', '.join(invalid_sub_profiles)))
 
 		custom_settings = profile_config.get('custom_settings', {})
-		for profile in valid:
-			profile.set_custom_settings(
-				custom_settings.get(profile.name, {})
-			)
-
-		if profile is not None:
-			profile.set_current_selection(valid)
+		profile.set_custom_settings(custom_settings)
+		profile.set_current_selection(valid_sub_profiles)
 
 		return profile
 


Test patch: