{"record":{"id":"ebe6116e090fc058","repo":"cube-js/cube","slug":"you-have-to-select-at-least-one-table","errorCode":null,"errorMessage":"You have to select at least one table","messagePattern":"You have to select at least one table","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cubejs-server-core/src/core/DevServer.ts","lineNumber":168,"sourceCode":"    app.get('/playground/files', catchErrors(async (req, res) => {\n      this.cubejsServer.event('Dev Server Files Load');\n      const files = await this.cubejsServer.repository.dataSchemaFiles();\n      res.json({\n        files: files.map(f => ({\n          ...f,\n          absPath: path.resolve(path.join(this.cubejsServer.repository.localPath(), f.fileName))\n        }))\n      });\n    }));\n\n    app.post('/playground/generate-schema', catchErrors(async (req, res) => {\n      this.cubejsServer.event('Dev Server Generate Schema');\n      if (!req.body) {\n        throw new Error('Your express app config is missing body-parser middleware. Typical config can look like: `app.use(bodyParser.json({ limit: \\'50mb\\' }));`');\n      }\n\n      if (!req.body.tables) {\n        throw new Error('You have to select at least one table');\n      }\n\n      const dataSource = req.body.dataSource || 'default';\n\n      const driver = await this.cubejsServer.getDriver({\n        dataSource,\n        authInfo: null,\n        securityContext: null,\n        requestId: getRequestIdFromRequest(req),\n      });\n      const tablesSchema = req.body.tablesSchema || (await driver.tablesSchema());\n\n      if (!Object.values(SchemaFormat).includes(req.body.format)) {\n        throw new Error(`Unknown schema format. Must be one of ${Object.values(SchemaFormat)}`);\n      }\n\n      const scaffoldingTemplate = new ScaffoldingTemplate(tablesSchema, driver, {\n        format: req.body.format,","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-server-core/src/core/DevServer.ts#L150-L186","documentation":"The generate-schema endpoint requires a non-empty `tables` array in the request body naming the tables to generate schemas for. If req.body.tables is falsy, this Error is thrown after the body-parser check.","triggerScenarios":"POSTing to /playground/generate-schema without a `tables` field, with `tables: null`, or with an empty selection from the schema-builder UI.","commonSituations":"Custom tooling calling the playground API directly; UI state where the user didn't tick any tables; API contract changes between client and server versions.","solutions":["Include tables in the POST body, e.g. { tables: ['public.orders'], format: 'yaml', dataSource: 'default' }","Fix the UI/client to always send the selected tables array","Validate the payload client-side before calling the endpoint"],"exampleFix":"// before\nawait fetch('/cubejs-system/v1/playground/generate-schema', { body: JSON.stringify({ format: 'yaml' }) });\n// after\nawait fetch('/cubejs-system/v1/playground/generate-schema', { body: JSON.stringify({ format: 'yaml', tables: ['public.orders'] }) });","handlingStrategy":"validation","validationCode":"const body = { tables: selectedTables, format: 'yaml', dataSource: 'default' };\nif (!Array.isArray(body.tables) || body.tables.length === 0) throw new Error('Select at least one table before generating schemas');","typeGuard":"const hasTables = (b: unknown): b is { tables: string[] } => typeof b === 'object' && b != null && Array.isArray((b as any).tables) && (b as any).tables.length > 0;","tryCatchPattern":"try { await generateSchema(body); } catch (e) { if (e.message === 'You have to select at least one table') { /* re-open table picker */ } else throw e; }","preventionTips":["Disable the generate action in the UI until a table is selected","Validate request bodies client-side","Keep client payloads in sync with the playground API contract","Send tables as an array, even for a single table"],"tags":["dev-server","validation","api"],"backgroundTag":"missing-request-field","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}