microsoft/semantic-kernel · error · KernelException
Failed to deserialize workflow.
Error message
Failed to deserialize workflow.
What it means
Thrown by `ExtractNodeInputs` when the requested `nodeId` cannot be found in the workflow YAML's `nodes` list, or when the matched node has no `inputs` mapping (or the inputs node is not a YAML mapping). The builder cannot proceed to extract input schemas without an inputs map. It is a KernelException.
Source
Thrown at dotnet/src/Experimental/Process.Core/Workflow/WorkflowBuilder.cs:664
}
#endregion
private Dictionary<string, JsonNode> ExtractNodeInputs(string nodeId)
{
var input = new StringReader(this._yaml ?? "");
var yamlStream = new YamlStream();
yamlStream.Load(input);
var rootNode = yamlStream.Documents[0].RootNode;
var agentsNode = rootNode["nodes"] as YamlSequenceNode;
var node = agentsNode?.Children
.OfType<YamlMappingNode>()
.FirstOrDefault(node => node["id"]?.ToString() == nodeId);
if (node is null || !node.Children.TryGetValue("inputs", out YamlNode? inputs) || input is null || inputs is not YamlMappingNode inputMap)
{
throw new KernelException("Failed to deserialize workflow.");
}
// This dance to convert the YamlMappingNode to a string and then back to a JsonSchema is rather inefficient, need to find a better option.
// Serialize the YamlMappingNode to a Yaml string
var serializer = new SerializerBuilder().Build();
string rawYaml = serializer.Serialize(inputMap);
// Deserialize the Yaml string to an object
var deserializer = new DeserializerBuilder().WithNamingConvention(UnderscoredNamingConvention.Instance).Build();
var yamlObject = deserializer.Deserialize(rawYaml);
// Serialize the object to a JSON string
var jsonSchema = JsonSerializer.Serialize(yamlObject);
var jsonNode = JsonNode.Parse(jsonSchema) ?? throw new KernelException("Failed to parse schema.");
var inputsDictionary = inputMap.Select(inputMap => new KeyValuePair<string, JsonNode>(inputMap.Key.ToString(), jsonNode))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
View on GitHub (pinned to c028a0c7dc)
Solutions
- Verify the node id exists under `nodes` and has an `inputs:` mapping (indented correctly under the node).
- Ensure `inputs` is a YAML map of key/value pairs, not a list or scalar.
- Confirm the YAML document is non-empty and well-formed (parse it standalone first).
Example fix
# before
nodes:
- id: agent1
type: myAgent
# after
nodes:
- id: agent1
type: myAgent
inputs:
message: "hello" Defensive patterns
Strategy: validation
Validate before calling
var node = workflow.Nodes.FirstOrDefault(n => string.Equals(n.Id, nodeId, StringComparison.Ordinal));
if (node is null)
throw new InvalidOperationException($"Node '{nodeId}' not found in workflow.");
if (node.Inputs is null || node.Inputs.Count == 0)
throw new InvalidOperationException($"Node '{nodeId}' has no inputs mapping.");
// then call ExtractNodeInputs(nodeId) Type guard
bool NodeHasInputs(Workflow wf, string nodeId) =>
wf.Nodes.FirstOrDefault(n => string.Equals(n.Id, nodeId, StringComparison.Ordinal))?.Inputs is { Count: > 0 }; Try / catch
try { var inputs = builder.ExtractNodeInputs(nodeId); }
catch (KernelException ex) when (ex.Message.Contains("Failed to deserialize workflow"))
{ _logger.LogError(ex, "Node '{NodeId}' missing or has no inputs mapping.", nodeId); throw; } Prevention
- Ensure every node that needs inputs has an inputs: mapping in YAML.
- Validate YAML indentation so inputs is a child of the node, not a sibling.
When it happens
Trigger: Call `ExtractNodeInputs(nodeId)` with an id that is not present under `nodes`; the node exists but omits the `inputs` key; the `inputs` value is a scalar/sequence instead of a mapping; the YAML document is empty or malformed so `Documents[0]` yields no root.
Common situations: Looking up inputs for a node that only has agent metadata; authoring a node without an `inputs:` block; whitespace/indentation errors making `inputs` parse as a sibling key; referencing a node id with different casing.
Related errors
- Failed to deserialize the process string.
- An orchestration is referencing a node with Id `{listenCondi
- A complete then action is required for orchestration steps.
- An orchestration is referencing a node with Id `{action.Node
- The process must have an Id set
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/612607e3ad0ca053.
Report an issue: GitHub.