microsoft/semantic-kernel · error · KernelException
[{s_namespace}] {name} resource not found
Error message
[{s_namespace}] {name} resource not found What it means
EmbeddedResource.Read constructs a resource name as '{namespace}.{name}' and calls GetManifestResourceStream. If no embedded resource matches that fully-qualified name, the stream is null. When throwIfNotFound is true (the default), KernelException is thrown listing the namespace and requested resource name.
Source
Thrown at dotnet/src/Experimental/Orchestration.Flow/EmbeddedResource.cs:25
internal static class EmbeddedResource
{
private static readonly string? s_namespace = typeof(EmbeddedResource).Namespace;
internal static string? Read(string name, bool throwIfNotFound = true)
{
var assembly = typeof(EmbeddedResource).GetTypeInfo().Assembly ??
throw new KernelException($"[{s_namespace}] {name} assembly not found");
using Stream? resource = assembly.GetManifestResourceStream($"{s_namespace}." + name);
if (resource is null)
{
if (!throwIfNotFound)
{
return null;
}
throw new KernelException($"[{s_namespace}] {name} resource not found");
}
using var reader = new StreamReader(resource);
return reader.ReadToEnd();
}
}
View on GitHub (pinned to c028a0c7dc)
Solutions
- Verify the resource file exists in the project and its Build Action is set to 'Embedded Resource'.
- Check the exact manifest resource name using Assembly.GetManifestResourceNames() to see what is actually embedded.
- Ensure the name passed to Read() matches the filename (without namespace prefix — the method adds it) exactly, including case.
- After renaming or moving resource files, rebuild to regenerate the manifest.
Example fix
// before — resource name doesn't match embedded file
var content = EmbeddedResource.Read("Prompts/OldPrompt.config");
// after — match the actual embedded resource name
// Check: typeof(EmbeddedResource).Assembly.GetManifestResourceNames()
var content = EmbeddedResource.Read("Prompts/NewPrompt.config"); Defensive patterns
Strategy: validation
Validate before calling
// Verify the resource exists before reading
var assembly = typeof(EmbeddedResource).GetTypeInfo().Assembly;
var fullName = $"{typeof(EmbeddedResource).Namespace}.{resourceName}";
if (assembly.GetManifestResourceNames().All(n => n != fullName))
{
throw new FileNotFoundException(
$"Embedded resource '{fullName}' not found. Available: {string.Join(", ", assembly.GetManifestResourceNames())}");
} Try / catch
try { var content = EmbeddedResource.Read(resourceName); }
catch (KernelException ex) when (ex.Message.Contains("resource not found"))
{
var available = typeof(EmbeddedResource).Assembly.GetManifestResourceNames();
logger.LogError("Resource '{Name}' not found. Embedded: {Names}", resourceName, string.Join(", ", available));
throw;
} Prevention
- Set Build Action to 'Embedded Resource' for all prompt/config files in the project.
- Run unit tests that load every embedded resource at build time to catch missing files early.
- After renaming resource files, update all code references and rebuild.
When it happens
Trigger: Calling EmbeddedResource.Read with a resource name that doesn't match any file embedded in the Orchestration.Flow assembly. The name must exactly match (including the namespace prefix that the method adds automatically).
Common situations: The .resourcemp or prompt file was renamed or removed from the project but code still references the old name. The file's Build Action is not 'Embedded Resource' so it isn't packaged. A typo in the resource name passed to Read(). Namespace changes after refactoring that break the prefixed name.
Related errors
- [{s_namespace}] {name} assembly not found
- Step {step.Goal} requires arguments {string.Join(",", step.R
- Failed to complete step {stepId} for session {sessionId}.
- Failed to deserialize execution state for sessionId={session
- CopilotAgent file not found: {filePath}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/7ca9655db9db6d95.
Report an issue: GitHub.