{"record":{"id":"3b18feffc3bc86a9","repo":"Tencent/WeKnora","slug":"no-memory-service","errorCode":null,"errorMessage":"no memory service","messagePattern":"no memory service","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/search_memory.go","lineNumber":108,"sourceCode":"\tvar input SearchMemoryInput\n\tif err := json.Unmarshal(args, &input); err != nil {\n\t\treturn &types.ToolResult{\n\t\t\tSuccess: false,\n\t\t\tError:   fmt.Sprintf(\"Failed to parse args: %v\", err),\n\t\t}, err\n\t}\n\tquery := strings.TrimSpace(input.Query)\n\tif query == \"\" {\n\t\treturn &types.ToolResult{\n\t\t\tSuccess: false,\n\t\t\tError:   \"query is required\",\n\t\t}, fmt.Errorf(\"missing query\")\n\t}\n\tif t.memoryService == nil {\n\t\treturn &types.ToolResult{\n\t\t\tSuccess: false,\n\t\t\tError:   \"long-term memory is not available\",\n\t\t}, fmt.Errorf(\"no memory service\")\n\t}\n\n\tlimit := input.Limit\n\tif limit <= 0 {\n\t\tlimit = types.MemorySearchDefaultItems\n\t}\n\tif limit > types.MemorySearchMaxItems {\n\t\tlimit = types.MemorySearchMaxItems\n\t}\n\n\tresult := t.memoryService.SearchMemory(ctx, query, limit)\n\n\t// \"Switched off\" and \"nothing stored matches\" have to reach the model as\n\t// different answers. Reporting an empty store to someone who turned memory\n\t// off would have the agent tell them it knows nothing about them, which is\n\t// both wrong and the opposite of what disabling memory was meant to do.\n\tif !result.Available {\n\t\treturn &types.ToolResult{","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/agent/tools/search_memory.go#L90-L126","documentation":"SearchMemoryTool.Execute returns \"no memory service\" when the tool's memoryService dependency is nil, meaning long-term memory is not wired up. The tool returns ToolResult Success=false with Error=\"long-term memory is not available\" plus this error. It is a dependency-injection guard: the tool exists but its backing store was never configured.","triggerScenarios":"Executing SearchMemoryTool after constructing it without a memory service (New... called with nil), or in a build/configuration where long-term memory is disabled but the tool is still registered with the agent.","commonSituations":"Memory backend (e.g. vector store) not initialized at startup; feature flag disabling long-term memory while tools are registered unconditionally; constructor dependency accidentally passed as nil; config missing memory connection settings.","solutions":["Initialize and pass a valid memory service when constructing SearchMemoryTool.","Unregister or skip registering the search-memory tool when long-term memory is disabled.","Verify memory backend configuration/connection at startup before the agent runs."],"exampleFix":"// before\ntool := tools.NewSearchMemoryTool(nil) // nil memoryService\n// after\nmemSvc, err := memory.NewService(cfg.Memory)\nif err != nil {\n    return fmt.Errorf(\"init memory service: %w\", err)\n}\ntool := tools.NewSearchMemoryTool(memSvc)","handlingStrategy":"type-guard","validationCode":"if memSvc == nil {\n    return errors.New(\"cannot register search-memory tool: memory service not configured\")\n}","typeGuard":"func memoryAvailable(t *tools.SearchMemoryTool, svc memory.Service) bool { return svc != nil }","tryCatchPattern":"res, err := tool.Execute(ctx, input)\nif err != nil && strings.Contains(err.Error(), \"no memory service\") {\n    // degrade gracefully: skip memory search or answer without recall\n}","preventionTips":["Initialize the memory service during startup and fail fast if it is nil","Only register memory tools when the memory backend is enabled","Add a startup health check for the memory backend connection"],"tags":["dependency-injection","memory","configuration"],"backgroundTag":"missing-dependency-not-configured","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}