Using a version of FSharp.Compiler.Service (FCS) higher than 9.0.1 in an Azure Function potentially causes runtime exceptions, because the Azure WebJobs SDK relies on FCS 9.0.1. Compilation succeeds, but version 9.0.1 is loaded at runtime instead of 11.0.6, which causes crashes when using functionality available in 11.0.6 but not in 9.0.1.
{
"frameworks": {
"net46":{
"dependencies": {
"FSharp.Compiler.Service": "11.0.6"
}
}
}
}
Exception while executing function: Functions.fsc-1. mscorlib: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
Compilation error.
Successful compilation but runtime exception.
Reverting to FSC 9.0.1
The following answer on StackOverflow describes the issue in more detail, with related information:
http://stackoverflow.com/a/42894076/114519
I can provide a smaller repro, if needed.
This is great. We have been considering some warnings/errors/restrictions when using package references that are bound to cause issues and this is definitely another candidate.
I think warnings would be a great start, this caused quite a bit of head-scratching on my end :)
More broadly, do you have any advice or plans to support a scenario like this one, where I'd want to use a version of a package that is not the same as the one that ships by default?
Generally, those scenarios should work, except for situations where you're relying on the binding types (e.g. storage triggers x storage references, DocumentDB bindings X DocumentDB references, etc.) or where you're clashing with built in binding redirects (which shouldn't be the case here. So I want to take a closer look at the binding failure to see what's going on.
Just for the record, very similar problem used to happen in FAKE, which is a build system based on F# Compiler Service (FCS) and hence it loads a fixed version of FCS in much the same way as Azure functions. We decided that restricting which version of FCS users can reference was a bit too restrictive and here is a discussion about possible solutions.
Currently, FAKE uses a workaround where the FCS assembly is renamed on build, so that FAKE use of the assembly does not clash with another version of assembly you might want to load on your own. It is quite hacky, but it seems to work... :shipit:
@tpetricek that is an interesting approach! Thanks for the pointers to the discussions (and the workaround)!
Should improve the error handling on this.
when a DLL cannot be loaded, the error message
Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information
get written into AppInsights, but is not helpful enough. It is unclear which DLL causes the issue. There needs to be more information.