CherryHQ/cherry-studio · warning · Error
Invalid totalThoughts: must be a number
Error message
Invalid totalThoughts: must be a number
What it means
The sequential-thinking server validates `totalThoughts` as a number with `!data.totalThoughts || typeof !== 'number'`. As with `thoughtNumber`, the `!data.totalThoughts` clause rejects `0`; valid values are >= 1. It throws a plain `Error`, returned as an `isError: true` tool result, not thrown to the caller. Note `totalThoughts` can be adjusted upward later — but it must always be a positive integer at submit time.
Source
Thrown at src/main/ai/mcp/servers/sequentialthinking.ts:39
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,
branchFromThought: data.branchFromThought as number | undefined,
branchId: data.branchId as string | undefined,
needsMoreThoughts: data.needsMoreThoughts as boolean | undefined
}
}
View on GitHub (pinned to 726446b54c)
Solutions
- Pass a positive integer estimate: `{ totalThoughts: 5 }` (adjustable later).
- Coerce and bound-check `>= 1` before dispatch.
- If unsure of the total, overestimate — the server allows `thoughtNumber > totalThoughts` and self-corrects.
Example fix
// before
{ totalThoughts: "5", ... }
// after
{ totalThoughts: 5, ... } Defensive patterns
Strategy: type-guard
Validate before calling
function normalizeTotalThoughts(v: unknown): number {
const n = typeof v === 'string' ? Number(v) : v
if (typeof n !== 'number' || !Number.isFinite(n) || n < 1) {
throw new TypeError("'totalThoughts' must be a number >= 1")
}
return Math.floor(n)
} Type guard
const isValidTotalThoughts = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 1
Try / catch
const result = await client.callTool({ name: 'sequentialthinking', arguments: { ...raw, totalThoughts: normalizeTotalThoughts(raw.totalThoughts) } })
if (result.isError) {
const body = JSON.parse((result.content[0] as any).text)
if (/totalThoughts/.test(body.error)) {/* pass a positive integer estimate */}
} Prevention
- Pass a positive integer estimate; overestimate if unsure — the server self-corrects upward.
- Coerce and bound-check before sending.
- Never use 0 to mean 'unknown'.
When it happens
Trigger: Submitting `totalThoughts` missing, null, a string, or `0`. Even though the server later raises `totalThoughts` to `thoughtNumber` if exceeded, both must be valid positive numbers at entry.
Common situations: The model passes a string estimate; omits the field; uses `0` to mean 'unknown'.
Related errors
- Invalid thought: must be a string
- Invalid thoughtNumber: 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/10f23985ff1f6f8c.
Report an issue: GitHub.