{"record":{"id":"8dc714f152332d3a","repo":"microsoft/semantic-kernel","slug":"agentdefinition-id-cannot-be-null-or-empty","errorCode":null,"errorMessage":"AgentDefinition.Id cannot be null or empty.","messagePattern":"AgentDefinition\\.Id cannot be null or empty\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Experimental/Process.Core/ProcessBuilder.cs","lineNumber":303,"sourceCode":"    }\n\n    /// <summary>\n    /// Adds a step to the process from a declarative agent.\n    /// </summary>\n    /// <param name=\"agentDefinition\">The <see cref=\"AgentDefinition\"/></param>\n    /// <param name=\"threadName\">Specifies the thread reference to be used by the agent. If not provided, the agent will create a new thread for each invocation.</param>\n    /// <param name=\"stepId\">Id of the step. If not provided, the Id will come from the agent Id.</param>\n    /// <param name=\"humanInLoopMode\">Specifies the human-in-the-loop mode for the agent. If not provided, the default is <see cref=\"HITLMode.Never\"/>.</param>\n    /// <param name=\"aliases\"></param>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentException\"></exception>\n    public ProcessAgentBuilder<TProcessState> AddStepFromAgentProxy<TProcessState>(AgentDefinition agentDefinition, string? threadName = null, string? stepId = null, HITLMode humanInLoopMode = HITLMode.Never, IReadOnlyList<string>? aliases = null) where TProcessState : class, new()\n    {\n        Verify.NotNull(agentDefinition, nameof(agentDefinition));\n\n        if (string.IsNullOrWhiteSpace(agentDefinition.Id))\n        {\n            throw new ArgumentException(\"AgentDefinition.Id cannot be null or empty.\", nameof(agentDefinition));\n        }\n\n        if (string.IsNullOrWhiteSpace(agentDefinition.Name))\n        {\n            throw new ArgumentException(\"AgentDefinition.Name cannot be null or empty.\", nameof(agentDefinition));\n        }\n\n        if (string.IsNullOrWhiteSpace(threadName))\n        {\n            // No thread name was specified so add a new thread for the agent.\n            this.AddThread(agentDefinition.Name, KernelProcessThreadLifetime.Scoped);\n            threadName = agentDefinition.Name;\n        }\n\n        KernelProcessStateResolver<string?> agentIdResolver = new((s) =>\n        {\n            StateResolverContentWrapper wrapper = new() { State = s };\n            var result = JMESPathConditionEvaluator.EvaluateToString(wrapper, agentDefinition.Id);","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.Core/ProcessBuilder.cs#L285-L321","documentation":"Thrown by ProcessBuilder.AddStepFromAgentProxy<TProcessState> when agentDefinition.Id is null, empty, or whitespace. The proxy agent variant requires Id because it constructs a KernelProcessStateResolver that evaluates agentDefinition.Id as a JMESPath expression at runtime to resolve the agent ID dynamically.","triggerScenarios":"Calling AddStepFromAgentProxy<TProcessState> with an AgentDefinition whose Id is null or whitespace. This overload has stricter requirements than AddStepFromAgent — it needs both Id (checked first) and Name (checked second).","commonSituations":"Using the proxy agent flow (AddStepFromAgentProxy) with a definition file that has 'name' but no 'id'. Confusing AddStepFromAgent (requires Name only) with AddStepFromAgentProxy (requires both Id and Name). JMESPath expression in the Id field that evaluates to null at runtime (though this specific throw is for the string being null/empty before resolution).","solutions":["Set agentDefinition.Id to a non-empty string (can be a JMESPath expression or literal agent ID) before calling AddStepFromAgentProxy.","If you do not need dynamic agent ID resolution, use AddStepFromAgent instead, which does not require Id.","Validate that the agent definition file includes a non-empty 'id' field when using the proxy pattern."],"exampleFix":"// before\nvar def = new AgentDefinition { Name = \"MyAgent\" }; // Id is null\nprocess.AddStepFromAgentProxy<MyState>(def); // throws\n\n// after\nvar def = new AgentDefinition { Id = \"$.agentId\", Name = \"MyAgent\" };\nprocess.AddStepFromAgentProxy<MyState>(def);","handlingStrategy":"validation","validationCode":"public static void EnsureAgentIdAndName(AgentDefinition def)\n{\n    if (string.IsNullOrWhiteSpace(def.Id))\n    {\n        throw new ArgumentException(\"AgentDefinition.Id is required for proxy agents.\", nameof(def));\n    }\n    if (string.IsNullOrWhiteSpace(def.Name))\n    {\n        throw new ArgumentException(\"AgentDefinition.Name is required for proxy agents.\", nameof(def));\n    }\n}","typeGuard":"public static bool HasAgentIdAndName(AgentDefinition def)\n    => !string.IsNullOrWhiteSpace(def.Id) && !string.IsNullOrWhiteSpace(def.Name);","tryCatchPattern":null,"preventionTips":["Ensure both 'id' and 'name' are present and non-empty in agent definition files for proxy agents.","Use AddStepFromAgent (not Proxy) if dynamic agent ID resolution is not needed.","Validate the Id field is a valid JMESPath expression or literal before calling AddStepFromAgentProxy."],"tags":["semantic-kernel","process-framework","agent-builder","agent-definition","proxy","validation","argument"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}