{"record":{"id":"7edabca405cca774","repo":"micro/go-micro","slug":"key-is-required","errorCode":null,"errorMessage":"key is required","messagePattern":"key is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gateway/mcp/mcp.go","lineNumber":495,"sourceCode":"\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn map[string]interface{}{\"keys\": keys}, nil\n\t\t},\n\t})\n\n\taddFramework(&Tool{\n\t\tName:        \"micro_store_read\",\n\t\tDescription: \"Read a record from the data store by key\",\n\t\tInputSchema: map[string]interface{}{\n\t\t\t\"type\": \"object\",\n\t\t\t\"properties\": map[string]interface{}{\n\t\t\t\t\"key\": map[string]interface{}{\"type\": \"string\", \"description\": \"Record key\"},\n\t\t\t},\n\t\t},\n\t\tHandler: func(input map[string]interface{}) (interface{}, error) {\n\t\t\tkey, _ := input[\"key\"].(string)\n\t\t\tif key == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"key is required\")\n\t\t\t}\n\t\t\trecords, err := store.Read(key)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif len(records) == 0 {\n\t\t\t\treturn map[string]interface{}{\"error\": \"not found\"}, nil\n\t\t\t}\n\t\t\treturn map[string]interface{}{\"key\": key, \"value\": string(records[0].Value)}, nil\n\t\t},\n\t})\n\n\taddFramework(&Tool{\n\t\tName:        \"micro_store_write\",\n\t\tDescription: \"Write a record to the data store\",\n\t\tInputSchema: map[string]interface{}{\n\t\t\t\"type\": \"object\",\n\t\t\t\"properties\": map[string]interface{}{","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/gateway/mcp/mcp.go#L477-L513","documentation":"The built-in store \"read\" MCP tool requires the \"key\" input parameter identifying the store record to fetch. An empty or missing key fails the guard before store.Read is called.","triggerScenarios":"An MCP client calls the store read tool with input {} or {\"key\": \"\"}; the handler short-circuits with \"key is required\" instead of reading from the store.","commonSituations":"LLM omits the key argument; caller assumed the tool would list all records instead of reading by key; key variable was empty because upstream data was missing.","solutions":["Pass a non-empty \"key\" string in the tool input: {\"key\": \"user:123\"}.","If you need a listing, check whether the store implementation offers a list capability instead of calling read with an empty key.","Validate that the key value is non-empty in the client before invoking the tool."],"exampleFix":"// before\ninput := map[string]interface{}{} // no key\n// after\ninput := map[string]interface{}{\"key\": \"user:123\"}","handlingStrategy":"validation","validationCode":"key, _ := input[\"key\"].(string)\nif key == \"\" {\n    return errors.New(\"store read requires a non-empty 'key' argument\")\n}","typeGuard":"func validKey(input map[string]interface{}) (string, bool) {\n    k, ok := input[\"key\"].(string)\n    return k, ok && k != \"\"\n}","tryCatchPattern":"records, err := callTool(\"store_read\", map[string]interface{}{\"key\": key})\nif err != nil {\n    if strings.Contains(err.Error(), \"key is required\") {\n        // supply the key and retry\n    }\n}","preventionTips":["Never pass an empty key hoping to list records — read is key-based only.","Sanitize/validate keys at the application layer before invoking the tool.","Check upstream data sources so the key variable can't be empty."],"tags":["mcp","validation","store"],"backgroundTag":"missing-required-argument","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}