CherryHQ/cherry-studio · warning · Error
Invalid nextThoughtNeeded: must be a boolean
Error message
Invalid nextThoughtNeeded: must be a boolean
What it means
The sequential-thinking server validates `nextThoughtNeeded` as a strict boolean (`typeof === 'boolean'`). Unlike the numeric fields it does NOT use a truthiness guard, so `0`/`1`/`"true"` are rejected. It throws a plain `Error`, returned as an `isError: true` tool result (not a thrown exception).
Source
Thrown at src/main/ai/mcp/servers/sequentialthinking.ts:42
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
}
}
private formatThought(thoughtData: ThoughtData): string {
const { thoughtNumber, totalThoughts, thought, isRevision, revisesThought, branchFromThought, branchId } =
thoughtDataView on GitHub (pinned to 726446b54c)
Solutions
- Always pass a real boolean: `{ nextThoughtNeeded: false }` on the final thought.
- Ensure your client does not stringify/numericize booleans before sending.
- Set `false` only when the chain is truly complete.
Example fix
// before
{ nextThoughtNeeded: "true", ... }
// after
{ nextThoughtNeeded: true, ... } Defensive patterns
Strategy: type-guard
Validate before calling
function asStrictBoolean(v: unknown): boolean {
if (typeof v === 'boolean') return v
throw new TypeError("'nextThoughtNeeded' must be a strict boolean (not 0/1/'true')")
} Type guard
const isStrictBoolean = (v: unknown): v is boolean => typeof v === 'boolean'
Try / catch
const result = await client.callTool({ name: 'sequentialthinking', arguments: { ...raw, nextThoughtNeeded: asStrictBoolean(raw.nextThoughtNeeded) } })
if (result.isError) {
const body = JSON.parse((result.content[0] as any).text)
if (/nextThoughtNeeded/.test(body.error)) {/* pass a real boolean */}
} Prevention
- Ensure your JSON serializer emits real booleans (not 0/1 or 'true'/'false').
- Set `false` only when the chain is truly complete.
- Validate all four required fields before each call.
When it happens
Trigger: Submitting `nextThoughtNeeded` as a truthy non-boolean: `1`, `0`, `"true"`, `"false"`, or omitted (undefined fails typeof).
Common situations: A JSON serializer coerces booleans to integers/strings; the model emits `"true"`; the field is omitted on the final thought.
Related errors
- Invalid thought: must be a string
- Invalid thoughtNumber: must be a number
- Invalid totalThoughts: must be a number
- 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/71fbd3a4bc38b8dd.
Report an issue: GitHub.