-edit2- Solved it by adding a dummy TValue parameter to the interface but I don't know why this is required. Code (CSharp): [JobProducerType(typeof(JobNativeMultiHashMapVisitUniqueKey.NativeMultiHashMapVisitUniqueKeyJobStruct<,,>))] public interface IJobNativeMultiHashMapVisitUniqueKey<TKey, TValue> where TKey : struct, IEquatable<TKey> where TValue : struct { void ExecuteNext(TKey key); } I feel like i'm either overlooking something or something is a little off. -original- I wrote a simple custom job, IJobNativeMultiHashMapVisitUniqueKey<T> Which is basically just a copy of IJobNativeMultiHashMapVisitKeyValue except only it only visits the first key Code (CSharp): // <copyright file="IJobNativeMultiHashMapVisitUniqueKey.cs" company="BovineLabs"> // Copyright (c) BovineLabs. All rights reserved. // </copyright> namespace BovineLabs.Common.Collections { using System; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Jobs; using Unity.Jobs.LowLevel.Unsafe; [JobProducerType(typeof(JobNativeMultiHashMapVisitUniqueKey.NativeMultiHashMapVisitUniqueKeyJobStruct<,,>))] public interface IJobNativeMultiHashMapVisitUniqueKey<in TKey> where TKey : struct, IEquatable<TKey> { void ExecuteNext(TKey key); } public static class JobNativeMultiHashMapVisitUniqueKey { internal struct NativeMultiHashMapVisitUniqueKeyJobStruct<TJob, TKey, TValue> where TJob : struct, IJobNativeMultiHashMapVisitUniqueKey<TKey> where TKey : struct, IEquatable<TKey> where TValue : struct { [ReadOnly] public NativeMultiHashMapImposter<TKey, TValue> HashMap; public TJob JobData; // ReSharper disable once StaticMemberInGenericType private static IntPtr JobReflectionData; public static IntPtr Initialize() { if (JobReflectionData == IntPtr.Zero) { JobReflectionData = JobsUtility.CreateJobReflectionData( typeof(NativeMultiHashMapVisitUniqueKeyJobStruct<TJob, TKey, TValue>), typeof(TJob), JobType.ParallelFor, (ExecuteJobFunction)Execute); } return JobReflectionData; } public delegate void ExecuteJobFunction( ref NativeMultiHashMapVisitUniqueKeyJobStruct<TJob, TKey, TValue> fullData, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex); public static unsafe void Execute( ref NativeMultiHashMapVisitUniqueKeyJobStruct<TJob, TKey, TValue> fullData, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex) { while (true) { if (!JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out var begin, out var end)) { return; } var buckets = (int*)fullData.HashMap.Buffer->Buckets; var keys = fullData.HashMap.Buffer->Keys; for (int i = begin; i < end; i++) { int entryIndex = buckets[i]; if (entryIndex != -1) { var key = UnsafeUtility.ReadArrayElement<TKey>(keys, entryIndex); fullData.JobData.ExecuteNext(key); } } } } } public static unsafe JobHandle Schedule<TJob, TKey, TValue>( this TJob jobData, NativeMultiHashMap<TKey, TValue> hashMap, int minIndicesPerJobCount, JobHandle dependsOn = default) where TJob : struct, IJobNativeMultiHashMapVisitUniqueKey<TKey> where TKey : struct, IEquatable<TKey>, IComparable<TKey> where TValue : struct { var imposter = (NativeMultiHashMapImposter<TKey, TValue>)hashMap; var fullData = new NativeMultiHashMapVisitUniqueKeyJobStruct<TJob, TKey, TValue> { HashMap = imposter, JobData = jobData, }; var scheduleParams = new JobsUtility.JobScheduleParameters( UnsafeUtility.AddressOf(ref fullData), NativeMultiHashMapVisitUniqueKeyJobStruct<TJob, TKey, TValue>.Initialize(), dependsOn, ScheduleMode.Batched); return JobsUtility.ScheduleParallelFor( ref scheduleParams, imposter.Buffer->BucketCapacityMask + 1, minIndicesPerJobCount); } } } It works fine in editor; appears to burst compile fine but as soon as I try to make a proper build burst throws errors even on an empty job Code (CSharp): [BurstCompile] public struct TESTJOB : IJobNativeMultiHashMapVisitUniqueKey<int> { public void ExecuteNext(int key) { } } with a very unhelpful error. Code (CSharp): BuildFailedException: Burst compiler (1.1.2) failed running stdout: Unexpected exception while processing type `BovineLabs.Vision.Jobs.TESTJOB` stderr: System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. at Mono.Collections.Generic.Collection`1.get_Item(Int32 index) at Burst.Compiler.IL.Syntax.GenericContext.Resolve(TypeReference typeReference) at Burst.Compiler.IL.Syntax.GenericContext.Resolve(TypeReference typeReference) at Burst.Compiler.IL.Syntax.GenericContext.Resolve(TypeReference typeReference) at Burst.Bcl.BclApp.FullyResolve(TypeReference tyRef, GenericContext ctx) at Burst.Bcl.BclApp.FullyResolve(MethodReference methodRef) at Burst.Bcl.BclApp.HashMethod(MethodReference methodRef) at Burst.Bcl.BclApp.FindExecuteMethods(List`1 rootAssemblyPaths) Can anyone spot anything I'm doing wrong? -edit- got a slightly more detailed error opening burst inspector Code (CSharp): ArgumentException: The number of generic arguments provided doesn't equal the arity of the generic type definition. Parameter name: instantiation System.RuntimeType.MakeGenericType (System.Type[] instantiation) (at <ad04dee02e7e4a85a1299c7ee81c79f6>:0) Unity.Burst.Editor.BurstReflection.FindExecuteMethods (UnityEditor.Compilation.AssembliesType assemblyTypes) (at Library/PackageCache/com.unity.burst@1.1.2/Editor/BurstReflection.cs:185) UnityEngine.Debug:LogException(Exception) Unity.Burst.Editor.BurstReflection:FindExecuteMethods(AssembliesType) (at Library/PackageCache/com.unity.burst@1.1.2/Editor/BurstReflection.cs:203) Unity.Burst.Editor.BurstInspectorGUI:OnGUI() (at Library/PackageCache/com.unity.burst@1.1.2/Editor/BurstInspectorGUI.cs:187) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)