{"record":{"id":"4d1332f60fa82b07","repo":"mastra-ai/mastra","slug":"a-numeric-theme-id-is-required","errorCode":null,"errorMessage":"A numeric theme id is required","messagePattern":"A numeric theme id is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playground-ui/src/ee/signals/hooks/theme-query-guards.ts","lineNumber":6,"sourceCode":"export function isNumericThemeId(themeId: string | undefined): themeId is string {\n  return themeId !== undefined && /^\\d+$/.test(themeId);\n}\n\nexport function requireNumericThemeId(themeId: string | undefined) {\n  if (!isNumericThemeId(themeId)) throw new Error('A numeric theme id is required');\n  return themeId;\n}\n\nexport function requireSnapshotId(snapshotId: string | undefined) {\n  if (!snapshotId) throw new Error('A theme snapshot is required');\n  return snapshotId;\n}\n","sourceCodeStart":1,"sourceCodeEnd":14,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/playground-ui/src/ee/signals/hooks/theme-query-guards.ts#L1-L14","documentation":"requireNumericThemeId validates that a theme id exists and consists only of digits (/^\\d+$/). The signals theme hooks (useThemeDetail, useThemeExamples, useThemeHistory) call it inside their query functions because the theme API only accepts numeric theme ids; a missing, empty, or non-numeric id (e.g., a slug or undefined while data loads) throws this error.","triggerScenarios":"Calling useThemeDetail/useThemeExamples/useThemeHistory with themeId undefined during route-param loading, or with a non-numeric id such as 'default', a UUID, or a slug; passing a user-supplied string id that includes non-digit characters.","commonSituations":"Route params not yet parsed when the query runs; theme selected from a list keyed by name rather than numeric id; API change returning string ids with prefixes; stale links containing old id formats.","solutions":["Ensure a numeric theme id is resolved (from route params or parent query) before enabling the query — gate with the hook's enabled option.","Convert or look up the id to its numeric form before calling the hook.","Validate the id with isNumericThemeId in the calling component and render a loading/error state when it fails.","Fix the data source returning non-numeric ids (e.g., strip prefixes or map slug → numeric id)."],"exampleFix":"// before\nconst { data } = useThemeDetail(themeId); // throws when themeId is 'theme-42'\n\n// after\nconst numericId = /^\\d+$/.test(themeId ?? '') ? themeId : undefined;\nconst { data } = useThemeDetail(numericId, { enabled: numericId !== undefined });","handlingStrategy":"type-guard","validationCode":"const isNumeric = (id: string | undefined) => id !== undefined && /^\\d+$/.test(id);\nif (!isNumeric(themeId)) return <ThemeIdMissing />; // skip the query","typeGuard":"function isNumericThemeId(themeId: string | undefined): themeId is string {\n  return themeId !== undefined && /^\\d+$/.test(themeId);\n}","tryCatchPattern":"try {\n  const id = requireNumericThemeId(routeParams.themeId);\n  // proceed with query\n} catch {\n  // show 'select a valid theme' empty state\n}","preventionTips":["Validate route params are numeric before rendering theme hooks.","Gate queries with enabled until a numeric id resolves.","Map slugs/prefixed ids to numeric ids at the data-source boundary.","Reuse isNumericThemeId from theme-query-guards instead of ad-hoc checks."],"tags":["validation","query-parameters","react-query","signals"],"backgroundTag":"invalid-identifier-format","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}