CherryHQ/cherry-studio · warning · Error
Invalid thought: must be a string
Error message
Invalid thought: must be a string
What it means
The sequential-thinking MCP server validates the `thought` field of each `sequentialthinking` call: it must be present and `typeof === 'string'`. It throws a plain `Error` (NOT an McpError). Crucially, `processThought` catches this error itself (line 126) and returns it as a tool result with `isError: true` and a JSON `{ error, status: 'failed' }` body — so the caller never sees a thrown exception, only a failed tool result.
Source
Thrown at src/main/ai/mcp/servers/sequentialthinking.ts:33
thoughtNumber: number
totalThoughts: number
isRevision?: boolean
revisesThought?: number
branchFromThought?: number
branchId?: string
needsMoreThoughts?: boolean
nextThoughtNeeded: boolean
}
class SequentialThinkingServer {
private thoughtHistory: ThoughtData[] = []
private branches: Record<string, ThoughtData[]> = {}
private validateThoughtData(input: unknown): ThoughtData {
const data = input as Record<string, unknown>
if (!data.thought || typeof data.thought !== 'string') {
throw new Error('Invalid thought: must be a string')
}
if (!data.thoughtNumber || typeof data.thoughtNumber !== 'number') {
throw new Error('Invalid thoughtNumber: must be a number')
}
if (!data.totalThoughts || typeof data.totalThoughts !== 'number') {
throw new Error('Invalid totalThoughts: must be a number')
}
if (typeof data.nextThoughtNeeded !== 'boolean') {
throw new Error('Invalid nextThoughtNeeded: must be a boolean')
}
return {
thought: data.thought,
thoughtNumber: data.thoughtNumber,
totalThoughts: data.totalThoughts,
nextThoughtNeeded: data.nextThoughtNeeded,
isRevision: data.isRevision as boolean | undefined,
revisesThought: data.revisesThought as number | undefined,View on GitHub (pinned to 726446b54c)
Solutions
- Always include a non-empty `thought` string in every call.
- Check the returned `isError` flag and `status: 'failed'` body rather than expecting an exception.
- Validate the four required fields client-side before calling (thought, thoughtNumber, totalThoughts, nextThoughtNeeded).
Example fix
// before
{ thought: "", thoughtNumber: 1, totalThoughts: 3, nextThoughtNeeded: true }
// after
{ thought: "Decompose the request into subproblems.", thoughtNumber: 1, totalThoughts: 3, nextThoughtNeeded: true } Defensive patterns
Strategy: validation
Validate before calling
function buildThoughtArgs(raw: unknown) {
if (typeof (raw as any)?.thought !== 'string' || (raw as any).thought.length === 0) {
throw new TypeError("'thought' must be a non-empty string")
}
return raw as { thought: string; thoughtNumber: number; totalThoughts: number; nextThoughtNeeded: boolean }
} Type guard
const hasThought = (v: unknown): v is { thought: string } =>
typeof v === 'object' && v !== null && typeof (v as any).thought === 'string' && (v as any).thought.length > 0 Try / catch
// This server returns soft errors, not thrown ones — check isError on the result.
const result = await client.callTool({ name: 'sequentialthinking', arguments: buildThoughtArgs(raw) })
if (result.isError) {
const body = JSON.parse((result.content[0] as any).text)
if (/Invalid thought/.test(body.error)) {/* rebuild args with a non-empty thought */}
} Prevention
- Always include a non-empty `thought` string.
- Check the tool result's `isError` flag — these errors do not throw.
- Validate all four required fields (thought, thoughtNumber, totalThoughts, nextThoughtNeeded) together.
When it happens
Trigger: Submitting a thought where `thought` is missing, null, a number, an object, or an empty string (the `!data.thought` guard also rejects `''`).
Common situations: The model passes only numeric fields; a client omits the prose; `thought` is templated from an empty variable.
Related errors
- Invalid thoughtNumber: must be a number
- Invalid totalThoughts: must be a number
- Invalid nextThoughtNeeded: must be a boolean
- InvalidParams
- Invalid command: command must be a non-empty string
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/4768684cb18bd7f7.
Report an issue: GitHub.