jd-opensource/joyagent-jdgenie · error · IllegalArgumentException

Unknown command: " + command

Error message

Unknown command: " + command

What it means

PlanningTool.execute looks up a handler in commandHandlers and throws IllegalArgumentException when the provided command has no registered handler. Supported commands are only those registered in the tool's handler map (e.g. create/delete/update).

Solutions

  1. Use only commands registered in commandHandlers (check the tool source/schema)
  2. Validate the command against the known set before calling execute
  3. Constrain the LLM tool schema to enumerate allowed commands

Example fix

// before
planningTool.execute(Map.of("command", "remove"));
// after
planningTool.execute(Map.of("command", "delete"));
Defensive patterns

Strategy: validation

Validate before calling

Set<String> allowed = Set.of("create","delete","update");
if (!allowed.contains(command)) { throw new IllegalArgumentException("unknown command: " + command); }

Try / catch

try {
    return planningTool.execute(params);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unknown command")) { /* map or reject command */ }
    throw e;
}

Prevention

When it happens

Trigger: Calling execute with command set to a value not in the handler map, e.g. "remove" instead of "delete", or a hallucinated command from the LLM.

Common situations: LLM inventing a command name not in the tool spec, renaming commands across versions, or typos in prompt/configured tool schemas.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08). Data as JSON: /api/errors/4af05b3b2206c604. Report an issue: GitHub.

Appendix: source

Thrown at genie-backend/src/main/java/com/jd/genie/agent/tool/common/PlanningTool.java:136

    @Override
    public Object execute(Object input) {
        if (!(input instanceof Map)) {
            throw new IllegalArgumentException("Input must be a Map");
        }

        Map<String, Object> params = (Map<String, Object>) input;
        String command = (String) params.get("command");

        if (command == null || command.isEmpty()) {
            throw new IllegalArgumentException("Command is required");
        }

        Function<Map<String, Object>, String> handler = commandHandlers.get(command);
        if (handler != null) {
            return handler.apply(params);
        } else {
            throw new IllegalArgumentException("Unknown command: " + command);
        }
    }

    private String createPlan(Map<String, Object> params) {
        String title = (String) params.get("title");
        List<String> steps = (List<String>) params.get("steps");

        if (title == null || steps == null) {
            throw new IllegalArgumentException("title, and steps are required for create command");
        }

        if (plan != null) {
            throw new IllegalStateException("A plan already exists. Delete the current plan first.");
        }

        plan = Plan.create(title, steps);
        return "我已创建plan";
    }

View on GitHub (pinned to 2417e0b8b6)