{"record":{"id":"d6bfb6e4b8e97c71","repo":"alibaba/arthas","slug":"task-aware-tools-registered-but-no-taskstore-confi","errorCode":null,"errorMessage":"Task-aware tools registered but no TaskStore configured. Add a TaskStore via .taskStore(store) or remove task tools.","messagePattern":"Task-aware tools registered but no TaskStore configured\\. Add a TaskStore via \\.taskStore\\(store\\) or remove task tools\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpServer.java","lineNumber":265,"sourceCode":"\n\t\tpublic StreamableServerNettySpecification taskStore(TaskStore<McpSchema.ServerTaskPayloadResult> taskStore) {\n\t\t\tAssert.notNull(taskStore, \"Task store must not be null\");\n\t\t\tthis.taskStore = taskStore;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic StreamableServerNettySpecification taskMessageQueue(TaskMessageQueue taskMessageQueue) {\n\t\t\tAssert.notNull(taskMessageQueue, \"Task message queue must not be null\");\n\t\t\tthis.taskMessageQueue = taskMessageQueue;\n\t\t\treturn this;\n\t\t}\n\n\t\tprotected void validateTaskConfiguration() {\n\t\t\tboolean hasTaskTools = !this.taskTools.isEmpty();\n\t\t\tboolean hasTaskStore = this.taskStore != null;\n\t\t\t\n\t\t\tif (hasTaskTools && !hasTaskStore) {\n\t\t\t\tthrow new IllegalStateException(\"Task-aware tools registered but no TaskStore configured. \"\n\t\t\t\t\t\t+ \"Add a TaskStore via .taskStore(store) or remove task tools.\");\n\t\t\t}\n\t\t\t// Note: Having taskStore without taskTools is allowed (for future dynamic registration)\n\t\t}\n\n\t\tprivate void assertNoDuplicateTool(String toolName) {\n\t\t\tfor (McpServerFeatures.ToolSpecification tool : this.tools) {\n\t\t\t\tif (tool.getTool().getName().equals(toolName)) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"Duplicate tool name: \" + toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (TaskAwareToolSpecification taskTool : this.taskTools) {\n\t\t\t\tif (taskTool.tool().getName().equals(toolName)) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"Duplicate tool name: \" + toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/protocol/server/McpServer.java#L247-L283","documentation":"Thrown at build() time of the McpNettyServer builder (StreamableServerNettySpecification.validateTaskConfiguration) when task-aware tools have been registered via taskTools(...) but no TaskStore was supplied via taskStore(...). The builder forbids this configuration because task tools need a store to persist task state; the inverse (store without task tools) is permitted for future dynamic registration.","triggerScenarios":"Calling .taskTools(...) one or more times on the builder, then calling .build() without ever calling .taskStore(...). Also when a TaskMessageQueue is set but the TaskStore is forgotten.","commonSituations":"Enabling the task-aware tool feature for the first time and missing the store wiring; refactoring that removed the taskStore() call but left task tools; following an incomplete example.","solutions":["Add .taskStore(new InMemoryTaskStore.Builder<>().build()) (or your custom TaskStore) to the builder chain before build().","Alternatively remove the .taskTools(...) calls if you do not need task-aware tool behavior.","Wire the TaskMessageQueue too if your tasks queue side-channel messages.","Review the full builder chain to confirm capabilities and store are consistent."],"exampleFix":"// before\nspec.taskTools(myTaskTool).build(); // IllegalStateException\n\n// after\nspec.taskStore(new InMemoryTaskStore.Builder<McpSchema.ServerTaskPayloadResult>().build())\n    .taskMessageQueue(new DefaultTaskMessageQueue())\n    .taskTools(myTaskTool)\n    .build();","handlingStrategy":"validation","validationCode":"// Validate builder state before build()\nboolean hasTaskTools = !taskToolSpecs.isEmpty();\nboolean hasStore = taskStore != null;\nif (hasTaskTools && !hasStore) {\n    throw new IllegalStateException(\"Configure taskStore before adding task tools\");\n}\n// then build()","typeGuard":null,"tryCatchPattern":"try {\n    spec.build();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"TaskStore\")) {\n        // fix wiring: add taskStore then rebuild\n        spec.taskStore(new InMemoryTaskStore.Builder<McpSchema.ServerTaskPayloadResult>().build());\n        spec.build();\n    } else throw e;\n}","preventionTips":["Always pair .taskTools(...) with .taskStore(...).","Add a startup self-test that asserts the builder config before build().","Keep builder configuration in one place to avoid partial wiring."],"tags":["mcp","task","builder","configuration","java"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}