I got "Unknown Hard Error" when I tried to run an editor script

Godot Version

4.7.2 Mono

Question

First time trying to run an EditorScript. I got the error box in the screen shot. As soon as I click the “Ok” button, Godot terminates immediately. What could be the reason for this?

And the script file simply transforms some PNG files in a directory. Gemini wrote it for me. I am sharing it below.

using Embodiment.Types;
using Godot;
using System.Collections.Generic;

namespace Embodiment.EditorScripts
{
	[Tool]
	public partial class PatternFileConverter : EditorScript
	{
		public override void _Run()
		{
			string rootDirectoryPath = "res://Game Data/Patterns";
			
			// 1. Build the Reverse Lookup Dictionary (Natural Color -> Material ID)
			Dictionary<Color, byte> colorToMaterialId = new Dictionary<Color, byte>();
			
			for (int i = 0; i < MaterialPresets.MAX_MATERIALS; i++)
			{
				var mat = MaterialPresets.materialsUnmanaged[i];
				if (mat.id != 0 || i == 0) // Skip empty slots, but keep Air (ID 0)
				{
					byte r = (byte) ( mat.color			& 0xFF);
					byte g = (byte) ((mat.color >> 8)	& 0xFF);
					byte b = (byte) ((mat.color >> 16)	& 0xFF);
					byte a = (byte) ((mat.color >> 24)	& 0xFF);
					
					Color godotColor = new Color(r / 255f, g / 255f, b / 255f, a / 255f);
					colorToMaterialId[godotColor] = mat.id;
				}
			}
			
			// 2. Scan recursively to find all _Colored.png files
			List<string> filesToProcess = new List<string>();
			CollectColoredFiles(rootDirectoryPath, filesToProcess);
			
			// 3. Process every collected file
			foreach (string file in filesToProcess)
			{
				ProcessImage(file, colorToMaterialId);
			}
			
			GD.Print($"Batch conversion complete! Processed {filesToProcess.Count} files.");
		}
		
		// Recursive method to dig through Cxxx and Byyy directories
		private void CollectColoredFiles(string currentPath, List<string> foundFiles)
		{
			using var dir = DirAccess.Open(currentPath);
			if (dir == null) return;
			
			// Find files in the current folder
			foreach (string file in dir.GetFiles())
			{
				if (file.EndsWith("_Colored.png"))
				{
					foundFiles.Add($"{currentPath}/{file}");
				}
			}
			
			// Find sub-folders and crawl them
			foreach (string subDir in dir.GetDirectories())
			{
				CollectColoredFiles($"{currentPath}/{subDir}", foundFiles);
			}
		}
		
		private void ProcessImage(string inputPath, Dictionary<Color, byte> lookup)
		{
			Image img = Image.LoadFromFile(inputPath);
			if (img.GetFormat() != Image.Format.Rgba8)
			{
				img.Convert(Image.Format.Rgba8);
			}
			
			int width = img.GetWidth();
			int height = img.GetHeight();
			
			Image dataImage = Image.CreateEmpty(width, height, false, Image.Format.Rgba8);

			for (int y = 0; y < height; y++)
			{
				for (int x = 0; x < width; x++)
				{
					Color pixelColor = img.GetPixel(x, y);
					
					if (lookup.TryGetValue(pixelColor, out byte materialId))
					{
						dataImage.SetPixel(x, y, new Color(0, materialId / 255f, 0, 1f));
					}
					else
					{
						dataImage.SetPixel(x, y, new Color(0, 0, 0, 1f));
					}
				}
			}
			
			string outputPath = inputPath.Replace("_Colored.png", ".png");
			dataImage.SavePng(outputPath);
			GD.Print($"Converted: {outputPath}");
		}
	}
}