herokuf#typeinitializeexception

Why does a record in an array cause a type initializer error in heroku?


I'm deploying an F# app to heroku as a script, and I'm having very strange problems. I'm getting the following error in the cases indicated below, but not the others:

System.TypeLoadException: Could not load type 'FSI_0007+Test[]' from assembly 'FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x410a5830 + 0x000b7> in :0

Error case:

type Test = { Test: string }
printfn "%A" [|{Test = "test"}|]  <--- error here

Working cases:

printfn "%A" [|"test"|]

type Test = { Test: string }
printfn "%A" {Test = "test"}

printfn "%A" [{Test = "test"}]

So it appears that I can't put records in arrays, but I can put any built-in types in arrays. Also, I can put records in lists. And records by themselves are fine.

Why does the combination of records plus arrays cause errors?

I'm using the buildpack here: https://github.com/SuaveIO/mono-script-buildpack

which uses mono-4.4.2.11.

It doesn't happen with local fsi in visual studio.


Solution

  • This looks very much like this bug in mono.

    I'm not exactly sure which versions of mono were affected by this and the reports in the bug discussion are a bit conflicting - but the latest stable version of mono 4.8.0 seems to work for at least one person...

    Another workaround would be to change your website to use fsproj so that the code is compiled and started as an executable (rather than using fsx file with runs via F# interactive) - I think compiled code does not suffer from this bug (or other potential bugs involving Mono Reflection).