microsoft/semantic-kernel · error · KernelException
Failed to deserialize schema.
Error message
Failed to deserialize schema.
What it means
Thrown during `BuildWorkflow` when converting a `UserStateType` property's JSON schema to a YAML schema object via YamlDotNet returns null. The library builds a JSON schema with `KernelJsonSchemaBuilder`, serializes it to a JSON string, and deserializes that string as YAML; a null result means the schema content could not be parsed into an object graph. It is a KernelException raised in the user-state-variable loop.
Source
Thrown at dotnet/src/Experimental/Process.Core/Workflow/WorkflowBuilder.cs:371
if (property.PropertyType == typeof(List<ChatMessageContent>))
{
workflow.Variables.Add(property.Name, new VariableDefinition()
{
Type = VariableType.Messages,
});
continue;
}
var schema = KernelJsonSchemaBuilder.Build(property.PropertyType);
var schemaJson = JsonSerializer.Serialize(schema.RootElement);
var deserializer = new DeserializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.IgnoreUnmatchedProperties()
.Build();
var yamlSchema = deserializer.Deserialize(schemaJson) ?? throw new KernelException("Failed to deserialize schema.");
workflow.Variables.Add(property.Name, new VariableDefinition { Type = VariableType.UserDefined, Schema = yamlSchema });
}
}
// Add edges
var orchestration = new List<OrchestrationStep>();
foreach (var edge in process.Edges)
{
// Get all the input events
OrchestrationStep orchestrationStep = new()
{
ListenFor = new ListenCondition()
{
From = "_workflow_",
Event = ResolveEventName(edge.Key)
},
Then = [.. edge.Value.Select(e => ThenAction.FromKernelProcessEdge(e, null))]
};View on GitHub (pinned to c028a0c7dc)
Solutions
- Inspect the generated JSON schema for the offending property by calling `KernelJsonSchemaBuilder.Build(prop.PropertyType)` directly and serializing it; confirm it is non-empty.
- Simplify or annotate the offending property type so schema generation produces a valid root element.
- If a property cannot be schema-fied, exclude it from UserStateType or wrap it in a type with a known schema.
Example fix
// before
public class MyUserState { public ComplexUnmappedType Weird { get; set; } }
// after (replace with a schema-serializable type)
public class MyUserState { public string Note { get; set; } } Defensive patterns
Strategy: try-catch
Validate before calling
foreach (var property in process.UserStateType?.GetProperties() ?? Array.Empty<PropertyInfo>())
{
if (property.PropertyType == typeof(List<ChatMessageContent>)) continue;
var schema = KernelJsonSchemaBuilder.Build(property.PropertyType);
var schemaJson = JsonSerializer.Serialize(schema.RootElement);
if (string.IsNullOrWhiteSpace(schemaJson) || schemaJson == "null")
throw new InvalidOperationException($"UserState property '{property.Name}' yields an empty schema.");
} Type guard
bool HasNonEmptySchema(Type t)
{
var s = KernelJsonSchemaBuilder.Build(t);
var json = JsonSerializer.Serialize(s.RootElement);
return !string.IsNullOrWhiteSpace(json) && json != "null";
} Try / catch
try { await WorkflowBuilder.BuildWorkflow(process); }
catch (KernelException ex) when (ex.Message.Contains("Failed to deserialize schema"))
{ _logger.LogError(ex, "A UserState property produced an un-deserializable schema; simplify its type."); throw; } Prevention
- Keep UserStateType properties to simple, schema-serializable CLR types.
- Unit-test schema generation for each UserStateType at design time.
- Avoid open generics or types without public parameterless constructors.
When it happens
Trigger: Declare a process `UserStateType` whose public property produces a JSON schema string that YamlDotNet deserializes to null (e.g. an effectively empty or malformed schema root element); a property type that `KernelJsonSchemaBuilder.Build` returns an empty/rootless schema for.
Common situations: Adding a complex or generic user-state property whose schema generation yields no usable root element; mismatches between the JSON schema builder version and the expected schema shape; using unsupported property types.
Related errors
- Failed to parse schema.
- Unsupported target type
- A complete then action is required for orchestration steps.
- The process must have an Id set
- Attempt to build a workflow node from step with no Id
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/95ddf5c0dc2dd8c7.
Report an issue: GitHub.