Could not load file or assembly, the system cannot find the file specified

Could not load file or assembly the system cannot find the file specified
Inicio » Informática » .Net » Could not load file or assembly, the system cannot find the file specified

Tabla de contenido

Últimamente he estado trabajando mucho con Azure Functions y lo cierto es que dan muchos quebraderos de cabeza en comparación con otro tipo de aplicaciones como pueden ser aplicaciones .NET MVC o APIs.

A continuación analizaremos por qué ocurre y cómo solucionar el error “Exception while executing function: FunctionName Could not load file or assembly ‘PackageName, Version=6.0.0.0, Culture=neutral, PublicKeyToken=Token’. The system cannot find the file specified.”.

¿Por qué y cómo ocurre este error?

Este error ocurre porque estamos utilizando Azure Functions en vez de otro tipo de aplicaciones como, por ejemplo, un API de .NET o una aplicación MVC.

Las Azure Functions tienen un entorno de ejecución más limitado, restringido o pequeño que otros tipos de aplicación y esto, a su vez, provoca que presenten más problemas, errores e incompatibilidades con las librerías que instalamos en ellas.

Por este motivo errores como el que se presenta en este artículo nunca los has visto en otro tipo de proyectos .NET donde su entorno de ejecución es más amplio y tienen a su disposición una base de librerías preinstaladas mayor.

La principal causa de estos errores se debe a que estamos utilizando, directa o indirectamente, una librería compatible para la versión .NET 6 dentro de una función .NET 8 o viceversa. Dicho de otro modo, los errores son provocados porque estamos usando librerías que no están en el entorno de ejecución limitado de las Azure functions. Si estuviéramos en un proyecto normal, como un API o una aplicación MVC, este tipo de incompatibilidades sería muy difícil de verlas.

Puedes verlo de la siguiente manera, una función de Azure está diseñada para ser un pequeño fragmento de código que se ejecute de manera rápida y eficiente en la nube (sin servidor o serverless) según varios desencadenadores.

Si queremos rapidez y rendimiento es necesario que estén optimizadas y, para optimizar, es necesario recortar o reducir por alguna parte. Uno de los puntos donde se produce dicha reducción es en el propio entorno de ejecución y esto, finalmente, nos lleva a más errores e incompatibilidades.

Uno de los problemas más peligrosos que debes tener en cuenta es que estos errores no se producen en tiempo de compilación ni publicación, sino que se producen en tiempo de ejecución.

Lo anterior significa que tu función va a compilar correctamente, no vas a tener ningún problema a la hora de publicar pero, cuando se esté ejecutando la parte de código afectada por la librería, dará una excepción.

Por ello, antes de analizar las posibles soluciones al error, te recomiendo que seas mucho más meticuloso con los test de una Azure Function que con una aplicación normal.

Mi recomendación es que realices una prueba por cada librería que utiliza tu aplicación. Por ejemplo, si tu aplicación de Azure Function utiliza Service Bus, Azure Cache for Redis y Blob Storage, te recomiendo que, a parte de las pruebas funcionales que siempre hacemos, realices una prueba por cada una de las tecnologías o librerías utilizadas.

Pasos previos a la solución del error

Para solucionar el error “Exception while executing function, could not load file or assembly” es necesario conocer previamente los siguientes puntos:

  • Versión de .NET utilizada por Azure Function. Para ello abriremos la función en Visual Studio, doble click sobre el nombre de la función y se abrirá el .csproj. Otra alternativa es abrir dicho fichero con un editor de texto plano.
    En nuestro caso la versión de .NET utilizada es la 8:
    <Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  • Paquete que provoca el error. El error se produce porque no encuentra una librería o paquete. Para conocer la librería que da error debemos observar el mensaje y fijarnos en lo que viene a continuación de “Could not load file or assembly”.
    En nuestro ejemplo el paquete es “System.Memory.Data”, versión 6.0.0.
    Exception while executing function: FunctionName Could not load file or assembly 'System.Memory.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=Token'. The system cannot find the file specified.
  • Dónde está el paquete que genera el error o quién lo utiliza. Como norma general este error no te dará con un paquete que hayas instalado directamente en tu proyecto sino que será un paquete hijo o transitorio de uno que sí has instalado tú directamente.
    Para encontrarlo iremos a “Dependencias”, “Paquetes” y dentro del listado iremos expandiendo nodos hasta que lo encontremos. Debemos fijarnos en el paquete raíz que lo contiene.
    En nuestro proyecto el paquete está bastante profundo en el árbol de dependencias y pertenece al paquete raíz “Microsoft.Azure.WebJobs.Extensions.ServiceBus”.
  • Cuando apareció el error. Aunque no es un punto obligatorio si que es muy interesante conocer a partir de qué momento o commit comenzó el error y qué lo provocó.
    Generalmente encontraremos un escenario donde antes funcionaba todo correctamente y a partir de que instalamos un paquete comenzó el error y nuestro sufrimiento.
    Siguiendo nuestro ejemplo podemos observar que el error comenzó a darse cuando instalamos el paquete “Azure.Identity” para otro desarrollo.
    Si comparamos los paquetes nos daremos cuenta que antes de la instalación de “Azure.Identity” teníamos la versión 1.0.2 de “System.Memory.Data” el cual no generaba ningún error y, tras la instalación del nuevo paquete, se ha cambiado a la versión 6.0.0 que si genera error:

Con todos los datos anteriores ya podemos proceder a ver las soluciones al error “Could not load file or assembly, the system cannot find the file specified”.

Verifica compatibilidad del paquete recién instalado

En nuestro caso hemos visto que el error proviene de la instalación de un paquete completamente distinto al que da error. Pues bien, vamos a comprobar que el nuevo paquete es compatible con nuestro framework:

  • Click derecho sobre el nombre de la función, “Administrar paquetes Nuget”.
  • Seleccionamos dentro del apartado de paquetes instalados el que acabamos de instalar, en nuestro caso “Azure.Identity”.
  • Comprueba que abajo, en dependencias, aparece la versión .NET de tu función.
    También puedes comprobarlo haciendo click en el enlace “nuget.org” que hay arriba a la derecha, esto abrirá una página donde deberás comprobar que el paquete es compatible con la versión .NET de tu función:

Si el paquete que has instalado no es compatible con el framework de tu Azure Function deberás actualizarlo a una versión que sí sea compatible o buscar una alternativa a ese paquete. Si no sabes hacerlo no te preocupes, más adelante lo veremos.

Comprobar compatibilidad del paquete raíz

¿Recuerdas que antes hemos revisado el paquete que da error “System.Memory.Data” y hemos descubierto que está dentro del paquete raíz “Microsoft.Azure.WebJobs.Extensions.ServiceBus”?.

Pues bien, lo que haremos ahora será verificar la compatibilidad del paquete raíz con la versión .NET de la función tal y como lo hemos hecho en el apartado anterior.

Si recuerdas, también comentamos que nuestra función se ejecuta en el entorno .NET 8, pues bien, el paquete raíz no es compatible con ese framework:

Las posibles soluciones a un paquete incompatible son:

  • Busca e instala actualizaciones del paquete a través del gestor de paquetes Nuget.
    En nuestro caso este paquete no tiene más actualizaciones y, por lo tanto, esta solución no nos sirve:
  • Busca una alternativa al paquete incompatible que sea compatible con tu framework y que cumpla con tus requisitos y necesidades. Obviamente, te va a tocar cambiar código en tus Azure Functions.
    En nuestro caso la alternativa al paquete incompatible es “Azure.Messaging.ServiceBus” que, como podéis observar, sí es compatible con .NET 8:
  • No obstante lo anterior no es del todo cierto, mirad qué hay cuando instalo dicho paquete en un proyecto completamente nuevo.
    Si amigos, tiene instalado el paquete “System.Memory.Data” versión 6.0.0, el causante del error “Exception while executing function, could not load file or assembly”.
    Por lo tanto esta solución en nuestro caso concreto no nos sirve, quizás en tu caso sí que sirva.

Instala manualmente el paquete que da error

Esta solución es sencilla aunque no siempre funciona. Consiste en analizar el error, ver qué paquete da error e instalarlo manualmente en el .csproj:

  • Lee atentamente el error y apunta el paquete y versión que no se puede cargar o encontrar.
    Could not load file or assembly 'System.Memory.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=Token'.
  • Añade una línea al .csproj con el nombre y la versión que te indica el error:
    <PackageReference Include="System.Memory.Data" Version="6.0.0.0" />
  • Limpia el proyecto, recompílalo y, si es necesario, súbelo de nuevo.

Tanto si los anteriores pasos te han funcionado como si no, intenta probar también a instalar una versión actualizada del paquete que da error, siempre verificando que la versión sea compatible con tu versión de .NET de las Azure Functions.

Si esta opción funciona es mejor tener dicho paquete actualizado que con una versión antigua.

En mi caso esta solución me ha funcionado en algún proyecto, aunque no en éste… Si a ti te ocurre lo mismo te recomiendo que sigas leyendo.

Fuerza la instalación de la .dll en el proyecto

Esta última solución siempre funciona para el error “Could not load file or assembly. The system cannot find the file specified.”. Simplemente consiste en añadir las siguientes líneas a tu fichero .csproj, acuérdate de cambiar el nombre del paquete que da error:

<ItemGroup>
	<FunctionsPreservedDependencies Include="System.Memory.Data.dll" />
</ItemGroup>

Esta línea lo que hace es forzar a la Azure Function a utilizar la .dll que le proporcionas y no la que las Azure Functions tienen en su entorno de ejecución.

A mi personalmente es una solución que no me gusta y debes utilizarla como último recurso, puedes tener problemas de incompatibilidades en otros paquetes, funcionamientos extraños… etc. Lo mejor es actualizar paquetes y, si no existen actualizaciones, buscar alternativas. No obstante, si has probado todas las soluciones anteriores como en nuestro ejemplo y ninguna de ellas te funciona, es la única opción.