Modules erroring, not describing where

Hey devs,

I’m using cmdr and I have a dynamic argument system, I’ve checked the docs but it won’t work.

Output:

ReplicatedStorage.CmdrClient.Shared.Util:115: invalid argument #1 to 'gmatch' (string expected, got nil)  -  Client - Util:115
  18:13:01.040  Stack Begin  -  Studio
  18:13:01.040  Script 'ReplicatedStorage.CmdrClient.Shared.Util', Line 115 - function SplitStringSimple  -  Studio - Util:115
  18:13:01.040  Script 'ReplicatedStorage.CmdrClient.Shared.Util', Line 250 - function ParsePrefixedUnionType  -  Studio - Util:250
  18:13:01.040  Script 'ReplicatedStorage.CmdrClient.Shared.Argument', Line 34 - function new  -  Studio - Argument:34
  18:13:01.040  Script 'ReplicatedStorage.CmdrClient.Shared.Command', Line 62 - function Parse  -  Studio - Command:62
  18:13:01.041  Script 'ReplicatedStorage.CmdrClient.Shared.Dispatcher', Line 44 - function Evaluate  -  Studio - Dispatcher:44
  18:13:01.041  Script 'ReplicatedStorage.CmdrClient.CmdrInterface', Line 31 - function OnTextChanged  -  Studio - CmdrInterface:31
  18:13:01.041  Script 'ReplicatedStorage.CmdrClient.CmdrInterface.Window', Line 341  -  Studio - Window:341
  18:13:01.041  Stack End  -  Studio
  18:13:01.125  ReplicatedStorage.CmdrClient.Shared.Util:115: invalid argument #1 to 'gmatch' (string expected, got nil)  -  Client - Util:115
  18:13:01.125  Stack Begin  -  Studio
  18:13:01.125  Script 'ReplicatedStorage.CmdrClient.Shared.Util', Line 115 - function SplitStringSimple  -  Studio - Util:115
  18:13:01.125  Script 'ReplicatedStorage.CmdrClient.Shared.Util', Line 250 - function ParsePrefixedUnionType  -  Studio - Util:250
  18:13:01.125  Script 'ReplicatedStorage.CmdrClient.Shared.Argument', Line 34 - function new  -  Studio - Argument:34
  18:13:01.126  Script 'ReplicatedStorage.CmdrClient.Shared.Command', Line 62 - function Parse  -  Studio - Command:62
  18:13:01.126  Script 'ReplicatedStorage.CmdrClient.Shared.Dispatcher', Line 44 - function Evaluate  -  Studio - Dispatcher:44
  18:13:01.126  Script 'ReplicatedStorage.CmdrClient.CmdrInterface', Line 31 - function OnTextChanged  -  Studio - CmdrInterface:31
  18:13:01.126  Script 'ReplicatedStorage.CmdrClient.CmdrInterface.Window', Line 341  -  Studio - Window:341
  18:13:01.126  Stack End  -  Studio
  18:13:01.744  ReplicatedStorage.CmdrClient.Shared.Util:115: invalid argument #1 to 'gmatch' (string expected, got nil)  -  Client - Util:115
  18:13:01.744  Stack Begin  -  Studio
  18:13:01.744  Script 'ReplicatedStorage.CmdrClient.Shared.Util', Line 115 - function SplitStringSimple  -  Studio - Util:115
  18:13:01.744  Script 'ReplicatedStorage.CmdrClient.Shared.Util', Line 250 - function ParsePrefixedUnionType  -  Studio - Util:250
  18:13:01.744  Script 'ReplicatedStorage.CmdrClient.Shared.Argument', Line 34 - function new  -  Studio - Argument:34
  18:13:01.745  Script 'ReplicatedStorage.CmdrClient.Shared.Command', Line 62 - function Parse  -  Studio - Command:62
  18:13:01.745  Script 'ReplicatedStorage.CmdrClient.Shared.Dispatcher', Line 44 - function Evaluate  -  Studio - Dispatcher:44
  18:13:01.745  Script 'ReplicatedStorage.CmdrClient.CmdrInterface', Line 31 - function OnTextChanged  -  Studio - CmdrInterface:31
  18:13:01.745  Script 'ReplicatedStorage.CmdrClient.CmdrInterface.Window', Line 341  -  Studio - Window:341
  18:13:01.746  Stack End  -  Studio

Script (client):

return {
	Name = "clans";
	Description = "Everything related to the clans system.";
	Group = "Moderator";
	Args = {
		{
			Type = "string";
			Name = "clan";
			Description = "The clan to change.";
		},
		function(context)
			return {
				Type = context.Cmdr.Util.MakeEnumType("option", {"Disband", "Kick", "Change Owner", "Change Rank", "Edit Info"}),
				Name = "action",
				Description = "The action you would like to do.",
			}
		end,
		function(context)
			local action = context:GetArgument(2):GetValue()

			if action == "Change Rank" then
				return {
					{
						Type = "player";
						Name = "player";
						Description = "Player whose rank is being changed.";
					},
					{
						Type = context.Cmdr.Util.MakeEnumType("option", {"High Commander", "Captain", "Member"}),
						Name = "rank",
						Description = "Rank to change player to.",
					}
				}
			elseif action == "Kick" then
				return {
					{
						Type = "player";
						Name = "player";
						Description = "Player who is being kicked.";
					}
				}
			elseif action == "Change Owner" then
				return {
					{
						Type = "player";
						Name = "newOwner";
						Description = "Player who will be the new owner.";
					}
				}
			elseif action == "Edit Info" then
				return {
					{
						Type = "string";
						Name = "description";
						Description = "New description for the clan.";
					},
					{
						Type = "integer";
						Name = "imageid";
						Description = "(optional) New image ID for the clan.";
						Optional = true;
					}
				}
			end
		end
	};
}

Documentation:

Introduction • Cmdr

Devforum Thread:

Cmdr: A fully extensible and type safe command console for Roblox Developers - Resources / Community Resources - Developer Forum | Roblox

Is there any reason why this won’t work?

Thanks for your help! :heart:

I think this video can help you with that

It doesn’t provide anything related to dynamic arguments, but thanks for your contribution

(if it does, please tell me a timestamp)

I think it because you’re trying to return multiple arguments from a single dynamic argument function.

return {
	Name = "clans";
	Description = "Everything related to the clans system.";
	Group = "Moderator";
	Args = {
		{
			Type = "string";
			Name = "clan";
			Description = "The clan to change.";
		},
		{
			Type = context.Cmdr.Util.MakeEnumType("clanAction", {"Disband", "Kick", "Change Owner", "Change Rank", "Edit Info"}),
			Name = "action",
			Description = "The action you would like to do.",
		},
		function(context)
			local action = context:GetArgument(2):GetValue()
			
			if action == "Kick" or action == "Change Owner" or action == "Change Rank" then
				return {
					Type = "player";
					Name = action == "Change Owner" and "newOwner" or "player";
					Description = action == "Change Owner" 
						and "Player who will be the new owner." 
						or "Player who is being affected.";
				}
			elseif action == "Edit Info" then
				return {
					Type = "string";
					Name = "description";
					Description = "New description for the clan";
				return {
					Type = "none";
					Name = "none";
					Description = "";
					Optional = true;
				}
			end
		end,
		function(context)
			local action = context:GetArgument(2):GetValue()
			
			if action == "Change Rank" then
				return {
					Type = context.Cmdr.Util.MakeEnumType("rankOption", {"High Commander", "Captain", "Member"}),
					Name = "rank",
					Description = "Rank to change player to.",
				}
			elseif action == "Edit Info" then
				return {
					Type = "integer";
					Name = "imageid";
					Description = "New image ID for the clan.";
					Optional = true;
				}
			else
				return {
					Type = "none";
					Name = "none";
					Description = "";
					Optional = true;
				}
			end
		end
	};
}

That broke the entire script, could you elaborate? You can’t return “none”, plus

this needs to be

function(context)
			return {
				Type = context.Cmdr.Util.MakeEnumType("option", {"Disband", "Kick", "Change Owner", "Change Rank", "Edit Info"}),
				Name = "action",
				Description = "The action you would like to do.",
			}
		end,

Still need help on this.

@1NoFree is absolutely right. I opened up the source code for Cmdr and used your traceback to isolate the cause of the problem. If you would like an explanation on how exactly your code causes internal conflict with Cmdr, let me know, and I’ll elaborate.

Ultimately, it is in fact the nature of the return values from your dynamic arguments that are causing the problem. As per the Cmdr documentation, these functions must return an ArgumentContext type, which does not allow for a 2D array.

-- ILLEGAL
return {
	{
		Type = "player";
		Name = "player";
		Description = "Player who is being kicked.";
	}
}
-- LEGAL
return {
	Type = "player";
	Name = "player";
	Description = "Player who is being kicked.";
}

You need to restructure your return values to be a single dictionary as shown above. I suggest re-reading the dynamic arguments and inline types section of the Cmdr documentation if this change will interfere with how you hoped to design your arguments

1 Like

Could you put this into the code? I’ve been trying for 20 minutes now and no luck.

1 Like

are you using module script? Inside Cmdr Commands folder

1 Like

I am indeed.

image

1 Like

Okay so I followed your guy’s advice but I need some arguments to have 2 arguments, for example EditInfo or ChangeRank

return {
	Name = "clans";
	Description = "Everything related to the clans system.";
	Group = "Moderator";
	Args = {
		{
			Type = "string";
			Name = "clan";
			Description = "The clan to change.";
		},
		function(context)
			return {
				Type = context.Cmdr.Util.MakeEnumType("option", {"Disband", "Kick", "Change Owner", "Change Rank", "Edit Info"});
				Name = "action";
				Description = "The action you would like to do.";
			}
		end,
		function(context)
			local actionArgument = context:GetArgument(2);
			local action = actionArgument:GetValue()

			if action == "Change Rank" then
				return {
					Type = "player";
					Name = "player";
					Description = "Player whose rank is being changed.";
				};
			elseif action == "Kick" then
				return {
					Type = "player";
					Name = "player";
					Description = "Player who is being kicked.";
				};
			elseif action == "Change Owner" then
				return {
					Type = "player";
					Name = "newOwner";
					Description = "Player who will be the new owner.";
				};
			elseif action == "Edit Info" then
				return {
					Type = "string";
					Name = "description";
					Description = "New description for the clan.";
				};
			end
		end
	};
}

Any idea how yall could help?

1 Like

Still needing help on this. Been troubleshooting for about 2 hours now and nothing has worked.

Okay so I’ve had enough of troubleshooting and I’ve decided to just split it up into seperate scripts. Thanks for all your help though. If you are able to fix this issue, please reply to this: