Return not Returning to the original call within Recursive Loop, how do i fix that?

Godot Version

4.4

Question

Hello,
my function’s not returning an array while within my loop. Am I doing something wrong here

var returnArray: Array = createTab(nextLine, nextText, choiceName, indent)

full code bellow, im trying to make a dialog dictionary that branches out infinity.
is giving the error "Trying to assign value of type ‘Nil’ to a variable of type ‘Array’. It’s recursive so it should be looping all the way through and then bringing the return back right? or is there something else I need to do to make sure that it returns the array to the original call? Thank you!

func branchCreator(lineNumber: int, choiceEnum, choiceName, tabs): #WOOOOOO RECURSIVE FUNCTIONS LETS GO
	var indent = tabs
	var previousIndent: int = tabs
	var text: String = choiceName
	var nextText = allScript[lineNumber + 1]
	var nextLine = lineNumber + 1
	choiceName = {}
	
	choiceName[lineNumber] = [text, choiceEnum]
	
	if text.contains("->") == true: #gets amount of tabs
		var regex = RegEx.new()
		regex.compile("\t")
		var result = regex.search(text)
		if result != null:
			var string = result.get_string()
			indent = string.length()
		else:
			indent = 0
	
		while nextText.contains("\t"):
			var returnArray: Array = createTab(nextLine, nextText, choiceName, indent)
			print(str(returnArray))
			return choiceName
	else:
		return choiceName
		
func createTab(lineNumber: int, text, choiceName, choiceIndent: int):
	var newLineNumber = lineNumber + 1
	var assignedLine = assignLineType(allScript[lineNumber])
	var indentComparison = choiceIndent
	var indent
	
	if text.contains("->") == true: #gets amount of tabs and checks if its a choice
		var regex = RegEx.new()
		regex.compile("\t")
		var result = regex.search(text)
		if result != null:
			var string = result.get_string()
			indent = string.length()
		else:
			indent = 0
		if indent <= choiceIndent:
			return [lineNumber, text, choiceName]
			#end and go back to loop
		if indent > choiceIndent:
			branchCreator(lineNumber, assignedLine, text, indent)
			#make a new branch
	else: #makes the tab and then makes another tab
		choiceName[lineNumber] = [text, assignedLine]
		createTab(newLineNumber, allScript[newLineNumber], choiceName, choiceIndent)

You only return once from createTab, maybe you mean to also return while recurseing? Setting a return value will help you find non-returned code paths

func createTab(lineNumber: int, text, choiceName, choiceIndent: int) -> Array: # Set Array return value
	# etc...
	else: #makes the tab and then makes another tab
		choiceName[lineNumber] = [text, assignedLine]
		# add return here?
		return createTab(newLineNumber, allScript[newLineNumber], choiceName, choiceIndent)

nope still says "Trying to assign value of type ‘Nil’ to a variable of type ‘Array’. and godot wont let me set array as the return value, gives "not all code paths return a value which is weird because they all have a value?

That is a valid error that is exceedingly relevant, you should keep the return type and fix the error. If one of your code paths does not return a value you will get 'Nil', find the missing code path, make all return an Array.

so i have no idea how to find which code path is missing a value, as far as I can tell they all have one. How would I go about finding whats missing/ could you explain what that error actually means? Google is not being super helpful on that front unfortunately. Thanks!

Every path the code could take must end up with a return statement, this doesn’t mean every if/else requires a return, but it’s good start. Go through each of your if/else statements and ask yourself if it should return a value? Seems like the call to branchCreator should too, especially as a else statement, so here’s what I’d propose and I think it’s fully qualified too, all code paths return as I’ve marked in the comments.

func createTab(lineNumber: int, text, choiceName, choiceIndent: int) -> Array:
	var newLineNumber = lineNumber + 1
	var assignedLine = assignLineType(allScript[lineNumber])
	var indentComparison = choiceIndent
	var indent

	if text.contains("->") == true:
		var regex = RegEx.new()
		regex.compile("\t")
		var result = regex.search(text)
		if result != null:
			var string = result.get_string()
			indent = string.length()
		else:
			indent = 0

		# one of these two will return, therefor this `if` will always return
		if indent <= choiceIndent:
			return [lineNumber, text, choiceName]
		else:
			return branchCreator(lineNumber, assignedLine, text, indent)

	else:
		choiceName[lineNumber] = [text, assignedLine]

		# this else will always return
		return createTab(newLineNumber, allScript[newLineNumber], choiceName, choiceIndent)

OMG thank you for the explanation. I had to make it output a dictionary instead because of the branch but still! it works! thanks!