sansan0/TrendRadar · error · InvalidParameterError

keyword 必须是字符串类型

Error message

keyword 必须是字符串类型

What it means

Raised by validate_keyword when keyword is truthy but not a str — e.g. an int, dict, or list. Note the check ordering: only truthiness is checked first, so keyword: 123 (truthy non-string) reaches the isinstance check and raises here, while keyword: 0 or [] is caught by the earlier '不能为空' branch instead.

Source

Thrown at mcp_server/utils/validators.py:499

def validate_keyword(keyword: str) -> str:
    """
    验证关键词

    Args:
        keyword: 搜索关键词

    Returns:
        处理后的关键词

    Raises:
        InvalidParameterError: 关键词无效
    """
    if not keyword:
        raise InvalidParameterError("keyword 不能为空")

    if not isinstance(keyword, str):
        raise InvalidParameterError("keyword 必须是字符串类型")

    keyword = keyword.strip()

    if not keyword:
        raise InvalidParameterError("keyword 不能为空白字符")

    if len(keyword) > 100:
        raise InvalidParameterError(
            "keyword 长度不能超过100个字符",
            suggestion="请使用更简洁的关键词"
        )

    return keyword


def validate_top_n(top_n: Optional[Union[int, str]], default: int = 10) -> int:
    """
    验证TOP N参数

View on GitHub (pinned to 8ee26026ba)

Solutions

  1. Pass a plain string: keyword: "人工智能" instead of ["人工智能"] or 123
  2. Client-side, coerce with String(keyword) when it is a number, and unwrap single-element arrays
  3. Validate the outbound payload against the tool schema before sending
  4. In strict TypeScript/Pyright codebases, type the parameter as string so this fails at compile time

Example fix

// before
{"keyword": ["AI 芯片"]}
// after
{"keyword": "AI 芯片"}
Defensive patterns

Strategy: type-guard

Validate before calling

if (Array.isArray(keyword)) keyword = keyword[0];
if (typeof keyword !== 'string') keyword = String(keyword); // or reject

Type guard

const isKeywordString = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;

Try / catch

try { call({ keyword }); }
catch (e) {
  if (/keyword 必须是字符串类型/.test(e.message)) call({ keyword: String(keyword) });
  else throw e;
}

Prevention

When it happens

Trigger: Passing keyword: 123, keyword: ["hot topics"], or keyword: {"text": "foo"} — e.g. an LLM wrapping the term in a list, or client code passing an ID or parsed JSON object where a string is expected.

Common situations: LLM tool calls guessing array-typed parameters; clients forwarding unserialized form data; variable reuse where a number ends up in the keyword slot; JSON payloads where a string field accidentally becomes a nested structure.

Related errors


AI-assisted analysis of sansan0/TrendRadar@8ee26026ba (2026-08-15). Data as JSON: /api/errors/228ad60a6cdff253. Report an issue: GitHub.