{"record":{"id":"ec47206247860799","repo":"conductor-oss/conductor","slug":"inspectplan-plan-is-required","errorCode":null,"errorMessage":"inspectPlan: plan is required","messagePattern":"inspectPlan: plan is required","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/AgentService.java","lineNumber":134,"sourceCode":"    /**\n     * /dg #6: compile a plan against a PLAN_EXECUTE harness config and return the resulting\n     * Conductor WorkflowDef — without dispatching it. Lets callers inspect what PAC would produce\n     * before running.\n     *\n     * <p>Uses the same {@link PlanAndCompileTask#inspectPlan(Map, String, String, int, Set, Map)}\n     * path the runtime SUB_WORKFLOW dispatch uses, so there's exactly one compiler — no\n     * inspect-only divergence.\n     *\n     * <p>Caller must supply both the agent config (so the compile knows about the tool list, model,\n     * harness timeout) and the plan (typically what the planner LLM emitted, but can be a\n     * hand-rolled static plan for offline validation).\n     */\n    public PlanAndCompileTask.InspectResult inspectPlan(InspectPlanRequest request) {\n        if (request == null || request.getAgentConfig() == null) {\n            throw new IllegalArgumentException(\"inspectPlan: agentConfig is required\");\n        }\n        if (request.getPlan() == null) {\n            throw new IllegalArgumentException(\"inspectPlan: plan is required\");\n        }\n        AgentConfig config = request.getAgentConfig();\n        if (config.getName() == null || config.getName().isEmpty()) {\n            config.setName(\"agent_inspect\");\n        }\n        if (config.getStrategy() != AgentConfig.Strategy.PLAN_EXECUTE) {\n            throw new IllegalArgumentException(\n                    \"inspectPlan: agentConfig.strategy must be 'plan_execute', got '\"\n                            + (config.getStrategy() == null\n                                    ? \"null\"\n                                    : config.getStrategy().toValue())\n                            + \"'\");\n        }\n\n        // Replicate what MultiAgentCompiler.compilePlanExecute computes\n        // before calling PAC at runtime — so the inspect compile sees the\n        // same inputs the real one would.\n        String workflowName = MultiAgentCompiler.planWorkflowName(config.getName());","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/AgentService.java#L116-L152","documentation":"Thrown by AgentService.inspectPlan when the InspectPlanRequest.plan field is null. The plan is the workflow plan (typically from the planner LLM or a hand-rolled static plan for offline validation) that the PAC task compiles into a WorkflowDef. Without it there is nothing to inspect. IllegalArgumentException maps to HTTP 400.","triggerScenarios":"Calling inspectPlan with agentConfig set but plan omitted; the planner LLM returned null or an empty response and it was passed through unchecked; the plan key was misspelled in the JSON request body.","commonSituations":"CI validation pipeline calls inspectPlan with only the config because the plan-generation step failed silently; integration with a planner service that returns null on error without the caller checking; JSON field name mismatch (e.g. 'workflow_plan' instead of 'plan').","solutions":["Ensure the planner output is non-null before constructing the InspectPlanRequest.","Validate request.getPlan() != null in the caller before calling inspectPlan.","If the plan comes from an LLM, add a null/empty guard on the planner response and fail earlier with a clearer message."],"exampleFix":"// before\nInspectPlanRequest req = new InspectPlanRequest();\nreq.setAgentConfig(config);\nreq.setPlan(plannerResult); // plannerResult is null -> error\n\n// after\nif (plannerResult == null) {\n    throw new IllegalStateException(\"Planner returned no plan\");\n}\nreq.setPlan(plannerResult);\nservice.inspectPlan(req);","handlingStrategy":"validation","validationCode":"if (request.getPlan() == null) {\n    throw new IllegalStateException(\"Planner produced no plan; cannot inspect\");\n}\nservice.inspectPlan(request);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Guard the planner LLM output for null/empty before building the request.","Log the planner response for debugging when it is null.","Ensure the plan JSON key matches 'plan' exactly."],"tags":["validation","inspect-plan","plan","bad-request"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}