mvanhorn/last30days-skill · error
%s is required
Error message
%s is required
What it means
Thrown by requireString (mcp/internal/tools/research.go:108) when a required argument key is entirely absent from the tool-call arguments map. In practice the only required string is 'topic' on the 'research' tool, so the user-facing message is "topic is required". This fires before any engine work happens: it is a cheap presence check distinct from the follow-up check that the value is a non-empty string. The tool schema marks topic with mcplib.Required(), so well-behaved clients should be prevented from sending the call at all.
Source
Thrown at mcp/internal/tools/research.go:108
runArgs := []string{topic, "--emit=" + emit, "--no-browser-cookies"}
if save {
runArgs = append(runArgs, "--save-dir", mcpSaveDir())
}
return runArgs
}
func mcpSaveDir() string {
saveDir := os.Getenv("LAST30DAYS_MEMORY_DIR")
if saveDir == "" {
return "~/Documents/Last30Days"
}
return saveDir
}
func requireString(args map[string]any, name string) (string, error) {
raw, ok := args[name]
if !ok {
return "", fmt.Errorf("%s is required", name)
}
value, ok := raw.(string)
if !ok || strings.TrimSpace(value) == "" {
return "", fmt.Errorf("%s must be a non-empty string", name)
}
return value, nil
}
func emitArgument(args map[string]any) (string, error) {
raw, ok := args["emit"]
if !ok {
return "compact", nil
}
value, ok := raw.(string)
if !ok {
return "", errors.New("emit must be a string")
}
switch value {View on GitHub (pinned to c7460f6114)
Solutions
- Include a non-empty "topic" string in the research tool arguments: {"topic": "OpenAI GPT-5"}.
- If building arguments programmatically, default the topic from user input and fail early in your own code with a clearer message before calling the tool.
- Client authors: honor the tool's inputSchema (topic is Required) and validate before dispatch.
Example fix
// before
{"name": "research", "arguments": {"emit": "html"}}
// -> error: topic is required
// after
{"name": "research", "arguments": {"topic": "rust 1.80 release", "emit": "html"}} Defensive patterns
Strategy: validation
Validate before calling
// Validate before calling the research tool.
func researchArgs(topic string, emit string, save bool) (map[string]any, error) {
if topic == "" {
return nil, errors.New("topic is required: ask the user what to research")
}
return map[string]any{"topic": topic, "emit": emit, "save": save}, nil
} Type guard
func hasResearchTopic(args map[string]any) bool {
_, ok := args["topic"]
return ok
} Prevention
- Always construct the arguments map with a literal "topic" key rather than building it dynamically from optional fields.
- Fail fast in your own code when no topic exists — your message can be more actionable than the server's generic one.
- Respect the tool schema: topic is marked Required, so client-side schema validation catches this before the round trip.
When it happens
Trigger: Calling the MCP 'research' tool with an arguments map that has no "topic" key at all — e.g. {} or {"emit": "html"}. Happens with hand-rolled JSON-RPC clients, a model omitting the parameter, or code that builds arguments dynamically and skips the key on an empty input instead of passing an empty string (which would produce the different 'must be a non-empty string' error).
Common situations: Direct JSON-RPC/mcp-go callers bypassing schema validation; agent models calling research with only optional flags; scripts that conditionally add keys and accidentally never set topic; test harnesses constructing argument maps by hand.
Related errors
- format must be 'text' or 'json', got %q
- %s must be a non-empty string
- emit must be 'compact' or 'html', got %q
- %s must be a boolean
- Unknown search source in {flag_name}: {source}
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/2fbc3782a1aa3f4a.
Report an issue: GitHub.