{"record":{"id":"4fb2e3f6b7d90343","repo":"jd-opensource/joyagent-jdgenie","slug":"step-index-is-required-for-mark-step-command","errorCode":null,"errorMessage":"step_index is required for mark_step command","messagePattern":"step_index is required for mark_step command","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"genie-backend/src/main/java/com/jd/genie/agent/tool/common/PlanningTool.java","lineNumber":178,"sourceCode":"        if (plan == null) {\n            throw new IllegalStateException(\"No plan exists. Create a plan first.\");\n        }\n\n        plan.update(title, steps);\n        return \"我已更新plan\";\n    }\n\n    private String markStep(Map<String, Object> params) {\n        Integer stepIndex = (Integer) params.get(\"step_index\");\n        String stepStatus = (String) params.get(\"step_status\");\n        String stepNotes = (String) params.get(\"step_notes\");\n\n        if (plan == null) {\n            throw new IllegalStateException(\"No plan exists. Create a plan first.\");\n        }\n\n        if (stepIndex == null) {\n            throw new IllegalArgumentException(\"step_index is required for mark_step command\");\n        }\n\n        plan.updateStepStatus(stepIndex, stepStatus, stepNotes);\n\n        return String.format(\"我已标记plan %d 为 %s\", stepIndex, stepStatus);\n    }\n\n    private String finishPlan(Map<String, Object> params) {\n        if (Objects.isNull(plan)) {\n            plan = new Plan();\n        } else {\n            for (int stepIndex = 0; stepIndex < plan.getSteps().size(); stepIndex++) {\n                plan.updateStepStatus(stepIndex, \"completed\", \"\");\n            }\n        }\n        return \"我已更新plan为完成状态\";\n    }\n","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/jd-opensource/joyagent-jdgenie/blob/2417e0b8b636d941ad5fb14c59b20dddfef5375d/genie-backend/src/main/java/com/jd/genie/agent/tool/common/PlanningTool.java#L160-L196","documentation":"markStep validates its arguments before delegating to plan.updateStepStatus. When the params map lacks `step_index`, it throws IllegalArgumentException because a step cannot be identified without its index.","triggerScenarios":"Calling PlanningTool with command=mark_step and a params map that omits `step_index` (only step_status/step_notes provided), or the LLM emitting malformed tool arguments.","commonSituations":"LLM generates incomplete tool-call JSON; caller builds the params map programmatically and forgets the index; schema drift between prompt documentation and tool implementation.","solutions":["Include `step_index` (integer, 0-based) in every mark_step call.","Validate tool-call arguments against the declared JSON schema before dispatching.","Improve the message to name the missing key and expected type for faster debugging."],"exampleFix":"// before\nInteger stepIndex = (Integer) params.get(\"step_index\");\n// after\nObject raw = params.get(\"step_index\");\nif (!(raw instanceof Integer stepIndex)) {\n    throw new IllegalArgumentException(\"step_index (integer) is required for mark_step command\");\n}","handlingStrategy":"validation","validationCode":"if (!params.containsKey(\"step_index\") || !(params.get(\"step_index\") instanceof Integer)) {\n    throw new IllegalArgumentException(\"mark_step requires integer step_index\");\n}","typeGuard":"static boolean hasStepIndex(Map<String, Object> params) {\n    return params.get(\"step_index\") instanceof Integer;\n}","tryCatchPattern":"try {\n    tool.execute(params);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"step_index is required\")) {\n        // fix args and retry with a valid step_index\n    } else throw e;\n}","preventionTips":["Validate tool-call JSON against the declared schema before dispatch.","Always include step_index in mark_step payload templates.","Constrain the LLM's tool schema so step_index is required."],"tags":["java","missing-argument","validation","agent-tooling"],"backgroundTag":"missing-required-argument","analyzedSha":"2417e0b8b636d941ad5fb14c59b20dddfef5375d","analyzedAt":"2026-09-08T11:28:19.414Z","contentChangedAt":"2026-09-08T11:28:19.414Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}