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

  1. Include a non-empty "topic" string in the research tool arguments: {"topic": "OpenAI GPT-5"}.
  2. 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.
  3. 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

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


AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15). Data as JSON: /api/errors/2fbc3782a1aa3f4a. Report an issue: GitHub.