microsoft/semantic-kernel · error · FileNotFoundException
CopilotAgent file not found: {filePath}
Error message
CopilotAgent file not found: {filePath} What it means
Thrown by CreatePluginFromCopilotAgentPluginAsync / ImportPluginFromCopilotAgentPluginAsync when the Copilot Agent Plugin manifest file does not exist on disk. The check is a plain File.Exists(filePath) before any parsing, so the path is resolved against the current process working directory, not the manifest or project directory.
Source
Thrown at dotnet/src/Functions/Functions.OpenApi.Extensions/Extensions/CopilotAgentPluginKernelExtensions.cs:73
/// <param name="cancellationToken">Optional cancellation token.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the created kernel plugin.</returns>
public static async Task<KernelPlugin> CreatePluginFromCopilotAgentPluginAsync(
this Kernel kernel,
string pluginName,
string filePath,
CopilotAgentPluginParameters? pluginParameters = null,
CancellationToken cancellationToken = default)
{
Verify.NotNull(kernel);
KernelVerify.ValidPluginName(pluginName, kernel.Plugins);
#pragma warning disable CA2000 // Dispose objects before losing scope. No need to dispose the Http client here. It can either be an internal client using NonDisposableHttpClientHandler or an external client managed by the calling code, which should handle its disposal.
var httpClient = HttpClientProvider.GetHttpClient(pluginParameters?.HttpClient ?? kernel.Services.GetService<HttpClient>());
#pragma warning restore CA2000
if (!File.Exists(filePath))
{
throw new FileNotFoundException($"CopilotAgent file not found: {filePath}");
}
var loggerFactory = kernel.LoggerFactory;
var logger = loggerFactory.CreateLogger(typeof(CopilotAgentPluginKernelExtensions)) ?? NullLogger.Instance;
using var CopilotAgentFileJsonContents = DocumentLoader.LoadDocumentFromFilePathAsStream(filePath,
logger);
var results = await PluginManifestDocument.LoadAsync(CopilotAgentFileJsonContents, new ReaderOptions
{
ValidationRules = [] // Disable validation rules
}).ConfigureAwait(false);
if (!results.IsValid)
{
var messages = results.Problems.Select(static p => p.Message).Aggregate(static (a, b) => $"{a}, {b}");
throw new InvalidOperationException($"Error loading the manifest: {messages}");
}
View on GitHub (pinned to c028a0c7dc)
Solutions
- Pass an absolute path: use Path.Combine(AppContext.BaseDirectory, "Plugins", "agent.json") or AppDomain.CurrentDomain.BaseDirectory to anchor the file relative to the assembly, not the CWD.
- Ensure the manifest file is marked CopyToOutputDirectory (PreserveNewest) in the .csproj so it lands beside the binary.
- Verify with File.Exists before calling, and log the fully-qualified path (Path.GetFullPath) to see where the runtime is actually looking.
- When loading from a Declarative Agent action, confirm the action.File value is relative to the DA manifest directory and that directory is itself correct.
Example fix
// before
var plugin = await kernel.ImportPluginFromCopilotAgentPluginAsync("MyPlugin", "agent.json", cancellationToken: ct);
// after
var fullPath = Path.Combine(AppContext.BaseDirectory, "Plugins", "agent.json");
var plugin = await kernel.ImportPluginFromCopilotAgentPluginAsync("MyPlugin", fullPath, cancellationToken: ct); Defensive patterns
Strategy: validation
Validate before calling
var fullPath = Path.GetFullPath(filePath);
if (!File.Exists(fullPath))
{
throw new FileNotFoundException($"Manifest not found at {fullPath}. CWD={Environment.CurrentDirectory}", fullPath);
}
var plugin = await kernel.CreatePluginFromCopilotAgentPluginAsync(pluginName, fullPath, pluginParameters, ct); Try / catch
try { var plugin = await kernel.ImportPluginFromCopilotAgentPluginAsync(name, fullPath, parameters, ct); }
catch (FileNotFoundException ex) when (ex.Message.Contains("CopilotAgent file not found"))
{
logger.LogError(ex, "Manifest path resolved to an missing file. Resolved={Path}", Path.GetFullPath(filePath));
throw;
} Prevention
- Anchor manifest paths to AppContext.BaseDirectory, not the CWD.
- Mark manifest files CopyToOutputDirectory=PreserveNewest in the .csproj.
- Log Path.GetFullPath(filePath) on startup to confirm where the runtime looks.
When it happens
Trigger: Calling kernel.CreatePluginFromCopilotAgentPluginAsync with a path that is wrong, misspelled, or relative to the wrong base directory. Also triggered when a Declarative Agent action references a CAP manifest via a relative File property whose base directory does not match the runtime CWD.
Common situations: Using a relative path that was correct at design time but the app runs from bin/Debug/net8.0/; deploying the manifest as content that was not copied to the output directory (missing CopyToOutputDirectory); passing a path with a leading slash that anchors at the filesystem root; cross-platform path separators on Linux vs Windows.
Related errors
- Error loading the manifest: {messages}
- No OpenAPI runtimes found in the manifest.
- Invalid manifest file path.
- Could not determine the assembly path.
- [{s_namespace}] {name} resource not found
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/e2929bcb600fe4b7.
Report an issue: GitHub.