{"record":{"id":"afd107b0fece9607","repo":"CherryHQ/cherry-studio","slug":"invalid-thoughtnumber-must-be-a-number","errorCode":null,"errorMessage":"Invalid thoughtNumber: must be a number","messagePattern":"Invalid thoughtNumber: must be a number","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/main/ai/mcp/servers/sequentialthinking.ts","lineNumber":36,"sourceCode":"  revisesThought?: number\n  branchFromThought?: number\n  branchId?: string\n  needsMoreThoughts?: boolean\n  nextThoughtNeeded: boolean\n}\n\nclass SequentialThinkingServer {\n  private thoughtHistory: ThoughtData[] = []\n  private branches: Record<string, ThoughtData[]> = {}\n\n  private validateThoughtData(input: unknown): ThoughtData {\n    const data = input as Record<string, unknown>\n\n    if (!data.thought || typeof data.thought !== 'string') {\n      throw new Error('Invalid thought: must be a string')\n    }\n    if (!data.thoughtNumber || typeof data.thoughtNumber !== 'number') {\n      throw new Error('Invalid thoughtNumber: must be a number')\n    }\n    if (!data.totalThoughts || typeof data.totalThoughts !== 'number') {\n      throw new Error('Invalid totalThoughts: must be a number')\n    }\n    if (typeof data.nextThoughtNeeded !== 'boolean') {\n      throw new Error('Invalid nextThoughtNeeded: must be a boolean')\n    }\n\n    return {\n      thought: data.thought,\n      thoughtNumber: data.thoughtNumber,\n      totalThoughts: data.totalThoughts,\n      nextThoughtNeeded: data.nextThoughtNeeded,\n      isRevision: data.isRevision as boolean | undefined,\n      revisesThought: data.revisesThought as number | undefined,\n      branchFromThought: data.branchFromThought as number | undefined,\n      branchId: data.branchId as string | undefined,\n      needsMoreThoughts: data.needsMoreThoughts as boolean | undefined","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/sequentialthinking.ts#L18-L54","documentation":"The sequential-thinking server validates `thoughtNumber` as a number with `!data.thoughtNumber || typeof !== 'number'`. Note the `!data.thoughtNumber` clause ALSO rejects `0` (falsy), so valid values must be >= 1. It throws a plain `Error`, caught and returned as an `isError: true` tool result (not a thrown exception).","triggerScenarios":"Submitting `thoughtNumber` missing, null, a string like `\"1\"`, or `0`. The advertised inputSchema enforces `minimum: 1`, matching the runtime `0` rejection.","commonSituations":"The model zero-indexes its thoughts; passes a stringified number; omits the field on a revision/branch call.","solutions":["Use a 1-based integer: `{ thoughtNumber: 1 }`.","Coerce with `Number(...)` and ensure `>= 1` before calling.","On revisions/branches, still pass a valid monotonic `thoughtNumber`."],"exampleFix":"// before\n{ thoughtNumber: 0, ... }\n// after\n{ thoughtNumber: 1, ... }","handlingStrategy":"type-guard","validationCode":"function normalizeThoughtNumber(v: unknown): number {\n  const n = typeof v === 'string' ? Number(v) : v\n  if (typeof n !== 'number' || !Number.isFinite(n) || n < 1) {\n    throw new TypeError(\"'thoughtNumber' must be a number >= 1\")\n  }\n  return Math.floor(n)\n}","typeGuard":"const isValidThoughtNumber = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v) && v >= 1","tryCatchPattern":"const result = await client.callTool({ name: 'sequentialthinking', arguments: { ...raw, thoughtNumber: normalizeThoughtNumber(raw.thoughtNumber) } })\nif (result.isError) {\n  const body = JSON.parse((result.content[0] as any).text)\n  if (/thoughtNumber/.test(body.error)) {/* use 1-based numbering and retry */}\n}","preventionTips":["Use 1-based integer thought numbers.","Coerce stringified numbers with `Number(...)` and bound-check `>= 1`.","Apply valid numbers on revision/branch calls too."],"tags":["mcp","validation","sequential-thinking","soft-error"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}