File.store_var() somehow causing a unicode parsing error

Godot Version

Godot 4.7.1 stable

Question

I’ve been rewriting my save system recently for a number of reasons, one of the main ones being that I can keep the data I don’t want reset on a hard reset/on different save files in a seperate dictionary and save that. However, after making all the changes, I’m getting a “unicode parse error” (actual screenshot a little below).

I’m saving the following dictionary with the following code (there is other code, but it isn’t relevant to this, I tried isolating this exact code and it did the same thing)(yes, there is a seperate reason META_PATH is a var instead of a const. I used the all caps naming scheme because it originally was a constant and had to be later changed due to an error it caused).

var metadata = {
	ID = 0,
	white_seen = false,
	savefile = 1,
	fun = 0,
}
var META_PATH
func _save() -> void:
	var file: FileAccess = FileAccess.open(META_PATH, FileAccess.WRITE)
	if FileAccess.get_open_error(): push_error("Error opening persistent data!"); return
	print(metadata)
	print(Marshalls.variant_to_base64(metadata))
	file.store_var(Marshalls.variant_to_base64(metadata))
	file.close()
	var file2: FileAccess = FileAccess.open(META_PATH, FileAccess.READ)
	if FileAccess.get_open_error(): push_error("Error opening persistent data!"); return
	print(file2.get_as_text())
	file2.close()

func _ready() --> void:
	META_PATH = "user://GAMEmetadata.json"
	_save()

And I get the following in the logs from this (the ID and fun variables are randomized in the ready function if they are the default, just too lazy to copy that over);

json error logs

I have absolutely no idea why this could be happening, given that it seems fine after it gets converted to base64. I’m fairly certain it has to do with the file.store_var() function, although I’m unsure what to do about that. I’m using this exact same save system for putting another dictionary into another file, and it works perfectly, as it had before I made any changes at all. Incase it’s relevant, the file is only used at runtime to copy the values over to be seen or changed in game. What gives? (Raw data from the file below).

store_var writes binary, not text. You’re putting a base64 string inside that binary format, then reading it with get_as_text(), which wants UTF-8. That’s the unicode error. Calling the file .json doesn’t make it JSON either.

If you want store_var, just do:

file.store_var(metadata)
# load:
var data = file.get_var()

No base64, no get_as_text().

If you actually want a text file / something you can open as JSON, use store_string with JSON.stringify(metadata) (or the base64 string), and read with get_as_text().

Your base64 print looking fine only means the encode worked. The write/read pair is mismatched.

Ah, I found the issue, thanks. It was that I was using get_as_text() in the load function to check if there was anything in the file, which did work given that it seems to just always return the first character, but it caused it to throw the error (and seemingly still doing it’s function). Probably should use !file.get_var() to check if theres anything there, and go off of that.

After doing that, it does seem like it worked, although I do wonder why the original data function (which used the same get_as_text() check) worked just fine without throwing any errors. Probably due to the first character of the base64 being something unable to be gotten as a string. Thanks for the help, I’ve just spent way too long trying to figure this out.