{"record":{"id":"457d7673079b73a4","repo":"nocobase/nocobase","slug":"sql-is-required","errorCode":null,"errorMessage":"sql is required","messagePattern":"sql is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/@nocobase/plugin-data-visualization/src/client-v2/flow/resources/ChartResource.ts","lineNumber":154,"sourceCode":"      contextParams: query.contextParams,\n    };\n    return data;\n  }\n\n  // 查询数据\n  async run() {\n    const data = this.request.data || {};\n    // 尝试从已有字段推断模式；但若无法推断则直接跳过，避免切换时抛错\n    const mode: 'sql' | 'builder' | undefined = data.mode ?? (data.sql ? 'sql' : undefined);\n\n    if (!mode) {\n      // 未配置模式时，认为尚未完成查询参数设置：不抛错、不请求 API，返回现有数据\n      return { data: this.getData(), meta: this.getMeta?.() };\n    }\n\n    if (mode === 'sql') {\n      if (!data.sql) {\n        throw new Error('sql is required');\n      }\n    } else {\n      // builder 模式\n      if (!data.collection || !data.measures?.length) {\n        throw new Error('collection and measures are required');\n      }\n    }\n\n    // 请求数据 api.post('charts:queryData')\n    return await this.runAction<TData, any>('queryData', this.getRefreshRequestOptions());\n  }\n\n  // debounce 刷新数据\n  async refresh() {\n    debugLog('---ChartResource refresh');\n    if (this.refreshTimer) {\n      clearTimeout(this.refreshTimer);\n    }","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/nocobase/nocobase/blob/fa42722fefe44265490dff2c27d79e2882bce4fa/packages/plugins/@nocobase/plugin-data-visualization/src/client-v2/flow/resources/ChartResource.ts#L136-L172","documentation":"ChartResource.run() in the data-visualization client-v2 executes a chart data query against the 'charts:queryData' API. When the chart's query mode is 'sql', the chart data must include a non-empty `sql` property; if it does not, the resource throws 'sql is required' before making any request, because a SQL-mode chart cannot produce results without a SQL statement.","triggerScenarios":"Calling run() on a chart whose `data.mode === 'sql'` while `data.sql` is undefined, null, or empty — e.g. the chart config was saved before the user typed a SQL statement, or config fields were renamed/stripped by a form or schema transform.","commonSituations":"Programmatically creating chart blocks via API or workflow with only mode='sql' set; a partial save of the chart settings form; copying chart options but forgetting the sql field; switching mode to 'sql' client-side without populating sql before calling run()/refresh().","solutions":["Set a non-empty `data.sql` value in the chart configuration before calling run()","Check chart settings UI: open the chart's query settings and paste/complete the SQL statement, then save","If creating charts programmatically, include `sql` in the data payload (e.g. { mode: 'sql', sql: 'SELECT ...' })","Use mode 'builder' instead if you intend to configure collection/measures rather than raw SQL"],"exampleFix":"// before\nawait chartResource.run({ data: { mode: 'sql' } });\n// after\nawait chartResource.run({ data: { mode: 'sql', sql: 'SELECT count(*) FROM users' } });","handlingStrategy":"validation","validationCode":"const chart = { mode: 'sql', sql: sqlInput };\nif (chart.mode === 'sql' && !chart.sql) {\n  throw new Error('Refusing to run: sql mode chart has no sql statement');\n}\nawait chartResource.run({ data: chart });","typeGuard":"function hasSqlChart(data: unknown): data is { mode: 'sql'; sql: string } {\n  return !!data && typeof data === 'object' && (data as any).mode === 'sql' && typeof (data as any).sql === 'string' && (data as any).sql.trim().length > 0;\n}","tryCatchPattern":"try {\n  await chartResource.run({ data: chartData });\n} catch (err) {\n  if (err.message === 'sql is required') {\n    openChartConfigPanel(); // prompt user to complete SQL settings\n  } else {\n    throw err;\n  }\n}","preventionTips":["Only call run()/refresh() after the chart settings form reports complete","When creating charts programmatically, always include sql for sql-mode charts","Validate chart payload shape in a shared helper before triggering queries"],"tags":["chart","sql","validation","client-side","data-visualization"],"backgroundTag":"missing-required-argument","analyzedSha":"fa42722fefe44265490dff2c27d79e2882bce4fa","analyzedAt":"2026-09-01T00:54:31.202Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}