What is the issue with my compute shader implementation?

I’ve been trying to implement a compute shader from Sebastian Lague’s marching cubes video into my own marching cubes project; however, unity is giving me cryptic errors from his code which shouldn’t make any sense since it worked totally fine for him. What is wrong with my project?
Screenshot 2023-07-05 163808

Here’s my chunk loading script:

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.Threading.Tasks;

public class Chunk : MonoBehaviour
{
    const int threadGroupSize = 8;

    public Material material;

    public Vector3Int chunkPos;
    public ComputeShader shader;

    private float[][][] blocks;

    public float isoLevel = .5f;

    public static Dictionary<Vector3Int, Chunk> chunks = new Dictionary<Vector3Int, Chunk>();
    public static Vector3Int size = new Vector3Int(16, 16, 16);

    Mesh mesh;
    public async void generate()
    {
        Vector3Int flPos = Vector3Int.RoundToInt(transform.position);
        chunkPos = Vector3Int.RoundToInt(new Vector3(flPos.x / size.x, flPos.y / size.y, flPos.z / size.z));

        if (!GetComponent<MeshFilter>())
            gameObject.AddComponent<MeshFilter>();
        if (!GetComponent<MeshRenderer>())
            gameObject.AddComponent<MeshRenderer>();
        mesh = new Mesh();

        await Task.Run(() => generateBlockArray());
        generateMesh();

        mesh.vertices = minimizedVerts.ToArray();
        mesh.triangles = adjustedTris.ToArray();

        mesh.RecalculateNormals();
        mesh.RecalculateBounds();

        try {
            GetComponent<MeshFilter>().mesh = mesh;
            GetComponent<MeshRenderer>().material = material;
        }
        catch { }

        chunks[chunkPos] = this;
    }

    ComputeBuffer triangleBuffer;
    ComputeBuffer pointsBuffer;
    ComputeBuffer triCountBuffer;
    List<int> adjustedTris;
    List<Vector3> minimizedVerts;
    void generateMesh()
    {
        int numVoxelsPerAxis = size.x;
        int numThreadsPerAxis = Mathf.CeilToInt (numVoxelsPerAxis / (float) threadGroupSize);

        int numPoints = (size.x+1)*(size.y+1)*(size.z+1);
        int numVoxels = numVoxelsPerAxis * numVoxelsPerAxis * numVoxelsPerAxis;
        int maxTriangleCount = numVoxels * 5;

        triangleBuffer = new ComputeBuffer(maxTriangleCount, sizeof(float) * 3 * 3, ComputeBufferType.Append);
        pointsBuffer = new ComputeBuffer(numPoints, sizeof(float) * 4);
        triCountBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);

        Vector4[] flattenedArray = new Vector4[numPoints];

        int index = 0;
        for (int x = 0; x < size.x; x++)
        {
            for (int y = 0; y < size.y; y++)
            {
                for (int z = 0; z < size.z; z++)
                {
                    flattenedArray[index] = new Vector4(x, y, z, blocks[x][y][z]);
                    index++;
                }
            }
        }

        pointsBuffer.SetData(flattenedArray);

        triangleBuffer.SetCounterValue(0);
        shader.SetBuffer(0, "points", pointsBuffer);
        shader.SetBuffer(0, "triangles", triangleBuffer);
        shader.SetInt("numPointsPerAxis", size.x+1);
        shader.SetFloat("isoLevel", isoLevel);

        shader.Dispatch(0, numThreadsPerAxis, numThreadsPerAxis, numThreadsPerAxis);

        // Get number of triangles in the triangle buffer
        ComputeBuffer.CopyCount (triangleBuffer, triCountBuffer, 0);
        int[] triCountArray = { 0 };
        triCountBuffer.GetData (triCountArray);
        int numTris = triCountArray[0];

        // Get triangle data from shader
        Triangle[] tris = new Triangle[numTris];
        triangleBuffer.GetData (tris, 0, 0, numTris);

        mesh = new Mesh();

        var vertices = new Vector3[numTris * 3];
        var meshTriangles = new int[numTris * 3];

        for (int i = 0; i < numTris; i++) {
            for (int j = 0; j < 3; j++) {
                meshTriangles[i * 3 + j] = i * 3 + j;
                vertices[i * 3 + j] = tris[i][j];
            }
        }

        minimizedVerts = new List<Vector3>();
        Dictionary<int, int> triPointers = new Dictionary<int, int>();
        for (int i = 0; i < vertices.Length; i++) {
            if (!minimizedVerts.Contains(vertices[i])) {
                minimizedVerts.Add(vertices[i]);
                triPointers[i] = minimizedVerts.Count - 1;
            }
            else
            {
                triPointers[i] = minimizedVerts.IndexOf(vertices[i]);
            }
        }

        adjustedTris = new List<int>();
        for (int i = 0; i < meshTriangles.Length; i++)
        {
            adjustedTris.Add(triPointers[meshTriangles[i]]);
        }
    }

    struct Triangle
    {
#pragma warning disable 649 // disable unassigned variable warning
        public Vector3 a;
        public Vector3 b;
        public Vector3 c;

        public Vector3 this[int i]
        {
            get
            {
                switch (i)
                {
                    case 0:
                        return a;
                    case 1:
                        return b;
                    default:
                        return c;
                }
            }
        }
    }

    Vector3 interpolateVerts(Vector4 v1, Vector4 v2)
    {
        float t = (isoLevel-v1.w) / (v2.w - v1.w);
        return v1 + t * (v2 - v1);
    }

    float getBlock(Vector3 pos)
    {
        if (pos.x < 0 || pos.y < 0 || pos.z < 0 || pos.x > size.z || pos.y > size.y || pos.z > size.z)
        {
            Vector3Int nPos = chunkPos + Vector3Int.FloorToInt(new Vector3(pos.x/(float)size.x, pos.y/(float)size.y, pos.z/(float)size.z));

            if (chunks.ContainsKey(nPos))
            {
                return chunks[nPos].getBlock(new Vector3Int((int)(pos.x+size.x)%size.x, (int)(pos.y+size.y)%size.y, (int)(pos.z + size.z)%size.z));
            }
            else
            {
                return -1;
            }
        }
        return blocks[(int)pos.x][(int)pos.y][(int)pos.z];
    }

    async Task generateBlockArray()
    {
        blocks = new float[(int)size.x+1][][];

        for (int x = 0; x < size.x+1; x++)
        {
            blocks[x] = new float[(int)size.y+1][];

            for (int y = 0; y < size.y+1; y++)
            {
                blocks[x][y] = new float[(int)size.z+1];

                for (int z = 0; z < size.z+1; z++)
                {
                    blocks[x][y][z] = generateBlock(new Vector3(x+chunkPos.x*size.x, y+chunkPos.y*size.y, z+chunkPos.z*size.z));
                }
            }
        }
    }

    float generateBlock(Vector3 pos)
    {
        float height = getHeight(pos.x, pos.z);
        return height - pos.y;
    }
    float smoothMax(float x, float y, float s)
    {
        return (x + y + Mathf.Sqrt(Mathf.Pow(x - y, 2) + s)) / 2;
    }
    float getHeight(float x, float y)
    {
        x += 1000;
        y += 234000;
        float height = 0;

        height += Mathf.PerlinNoise(x * .005f, y * .005f) * 20;
        float mountainBase = 40;
        float accumulationHeight = 10;
        float mountains = 0;
        mountains += Mathf.PerlinNoise(x * .01f, y * .01f) * 20;
        mountains += (1-Mathf.Abs(Mathf.PerlinNoise(x * .005f, y * .005f)-.5f)*2) * 60;
        mountains += (1 - Mathf.Abs(Mathf.PerlinNoise(x * .05f, y * .05f) - .5f) * 2) * 8;
        mountains = smoothMax(mountains, mountainBase, 20) - mountainBase;
        if (mountains > accumulationHeight) 
            mountains = accumulationHeight + Mathf.Pow((mountains - accumulationHeight), 2)/15;
        height += mountains;
        height += Mathf.PerlinNoise(x * .1f, y * .1f) * 3;

        return height;
    }
}

[CustomEditor(typeof(Chunk))]
public class GenerateChunkEditor : Editor
{
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        Chunk chunk = (Chunk)target;
        if (GUILayout.Button("Generate Chunk"))
        {
            Debug.Log("Generated Chunk");
            chunk.generate();
        }
    }
}

Here’s Sebastian Lague’s compute shader that I’m using:

#pragma kernel March
#include "MarchTables.compute"

static const int numThreads = 8;

struct Triangle
{
    float3 vertexC;
    float3 vertexB;
    float3 vertexA;
};

AppendStructuredBuffer<Triangle> triangles;
RWStructuredBuffer<float4> points;

int numPointsPerAxis;
float isoLevel;

float3 interpolateVerts(float4 v1, float4 v2)
{
    float t = (isoLevel - v1.w) / (v2.w - v1.w);
    return v1.xyz + t * (v2.xyz - v1.xyz);
}

int indexFromCoord(int x, int y, int z)
{
    return z * numPointsPerAxis * numPointsPerAxis + y * numPointsPerAxis + x;
}
[numthreads(numThreads, numThreads, numThreads)]
void March(int3 id : SV_DispatchThreadID)
{
    // Stop one point before the end because voxel includes neighbouring points
    if (id.x >= numPointsPerAxis - 1 || id.y >= numPointsPerAxis - 1 || id.z >= numPointsPerAxis - 1)
    {
        return;
    }

    // 8 corners of the current cube
    float4 cubeCorners[8] =
    {
        points[indexFromCoord(id.x, id.y, id.z)],
        points[indexFromCoord(id.x + 1, id.y, id.z)],
        points[indexFromCoord(id.x + 1, id.y, id.z + 1)],
        points[indexFromCoord(id.x, id.y, id.z + 1)],
        points[indexFromCoord(id.x, id.y + 1, id.z)],
        points[indexFromCoord(id.x + 1, id.y + 1, id.z)],
        points[indexFromCoord(id.x + 1, id.y + 1, id.z + 1)],
        points[indexFromCoord(id.x, id.y + 1, id.z + 1)]
    };

    // Calculate unique index for each cube configuration.
    // There are 256 possible values
    // A value of 0 means cube is entirely inside surface; 255 entirely outside.
    // The value is used to look up the edge table, which indicates which edges of the cube are cut by the isosurface.
    int cubeIndex = 0;
    if (cubeCorners[0].w < isoLevel)
        cubeIndex |= 1;
    if (cubeCorners[1].w < isoLevel)
        cubeIndex |= 2;
    if (cubeCorners[2].w < isoLevel)
        cubeIndex |= 4;
    if (cubeCorners[3].w < isoLevel)
        cubeIndex |= 8;
    if (cubeCorners[4].w < isoLevel)
        cubeIndex |= 16;
    if (cubeCorners[5].w < isoLevel)
        cubeIndex |= 32;
    if (cubeCorners[6].w < isoLevel)
        cubeIndex |= 64;
    if (cubeCorners[7].w < isoLevel)
        cubeIndex |= 128;

    // Create triangles for current cube configuration
    for (int i = 0; triangulation[cubeIndex][i] != -1; i += 3)
    {
        // Get indices of corner points A and B for each of the three edges
        // of the cube that need to be joined to form the triangle.
        int a0 = cornerIndexAFromEdge[triangulation[cubeIndex][i]];
        int b0 = cornerIndexBFromEdge[triangulation[cubeIndex][i]];

        int a1 = cornerIndexAFromEdge[triangulation[cubeIndex][i + 1]];
        int b1 = cornerIndexBFromEdge[triangulation[cubeIndex][i + 1]];

        int a2 = cornerIndexAFromEdge[triangulation[cubeIndex][i + 2]];
        int b2 = cornerIndexBFromEdge[triangulation[cubeIndex][i + 2]];

        Triangle tri;
        tri.vertexA = interpolateVerts(cubeCorners[a0], cubeCorners[b0]);
        tri.vertexB = interpolateVerts(cubeCorners[a1], cubeCorners[b1]);
        tri.vertexC = interpolateVerts(cubeCorners[a2], cubeCorners[b2]);
        triangles.Append(tri);
    }


}