{"record":{"id":"79e6864c6b41a8a8","repo":"tldraw/tldraw","slug":"clusterids-is-required-a-cluster-id-or-an-array","errorCode":null,"errorMessage":"clusterIds is required: a cluster id, or an array of them","messagePattern":"clusterIds is required: a cluster id, or an array of them","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/dotcom/sync-worker/src/routes/tla/sharedBoardScreenshotMcp.ts","lineNumber":347,"sourceCode":"\tpage: PageSelector\n\tclusterIds: string[]\n\ttheme: 'light' | 'dark'\n} {\n\tconst value = requireArgumentsObject(input)\n\treturn {\n\t\tboardId: parseBoardId(value.boardId),\n\t\tpage: parsePageSelector(value.page),\n\t\tclusterIds: parseClusterIds(value.clusterIds),\n\t\ttheme: parseTheme(value.theme),\n\t}\n}\n\n// Accepts one id or several. A single string is allowed because asking for one cluster is the common\n// case and making callers wrap it in an array is friction for nothing.\nexport function parseClusterIds(value: unknown): string[] {\n\tif (typeof value === 'string') return [parseClusterId(value)]\n\tif (!Array.isArray(value) || value.length === 0) {\n\t\tthrow new Error('clusterIds is required: a cluster id, or an array of them')\n\t}\n\treturn value.map((id) => parseClusterId(id))\n}\n\nexport function parseClusterId(value: unknown): string {\n\tif (typeof value !== 'string' || value.length === 0) {\n\t\tthrow new Error('clusterId is required')\n\t}\n\treturn value\n}\n\nfunction requireArgumentsObject(input: unknown): Record<string, unknown> {\n\tif (!input || typeof input !== 'object') {\n\t\tthrow new Error('Tool arguments must be an object')\n\t}\n\treturn input as Record<string, unknown>\n}\n","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/tldraw/tldraw/blob/b31086b44731a7d1d9d46be4163ac8ef7417321d/apps/dotcom/sync-worker/src/routes/tla/sharedBoardScreenshotMcp.ts#L329-L365","documentation":"Thrown by parseClusterIds when value is not a string and not a non-empty array. parseClusterScreenshotInput calls it to validate the clusterIds argument for the take-cluster-screenshots MCP tool. A single string is accepted (wrapped into [value]) for convenience; anything else — undefined, null, an empty array, an object, a number — is rejected.","triggerScenarios":"MCP tool call to take_cluster_screenshots (or parseClusterScreenshotInput directly) with clusterIds omitted, set to null, an empty array [], or a non-array non-string value. Each element must itself pass parseClusterId.","commonSituations":"LLM/caller omits clusterIds assuming a default; passes an array of objects instead of strings; passes a comma-separated string (which would be treated as one id and fail parseClusterId).","solutions":["Provide clusterIds as a single id string or an array of id strings: {\"clusterIds\":\"abc\"} or {\"clusterIds\":[\"abc\",\"def\"]}.","If you have a comma-separated list, split it into an array before passing.","Ensure every element is a non-empty string."],"exampleFix":"// before\n{ \"clusterIds\": \"a,b,c\" }   // treated as one id, parseClusterId may reject\n// after\n{ \"clusterIds\": [\"a\",\"b\",\"c\"] }","handlingStrategy":"validation","validationCode":"function asClusterIds(value: unknown): string[] {\n  if (typeof value === 'string') return [value]\n  if (Array.isArray(value) && value.length > 0) return value.filter((v): v is string => typeof v === 'string' && v.length > 0)\n  throw new Error('clusterIds is required: a cluster id, or an array of them')\n}","typeGuard":"function isClusterIdsInput(value: unknown): value is string | string[] {\n  return typeof value === 'string' || (Array.isArray(value) && value.every((v) => typeof v === 'string' && v.length > 0) && value.length > 0)\n}","tryCatchPattern":null,"preventionTips":["Pass clusterIds as a single id string or an array of id strings.","Split comma-separated lists into arrays before sending.","Filter out empty/null elements from arrays."],"tags":["mcp","validation","screenshots","clusters"],"backgroundTag":null,"analyzedSha":"b31086b44731a7d1d9d46be4163ac8ef7417321d","analyzedAt":"2026-08-12T17:05:39.947Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}