nocobase/nocobase · error · FlowSurfaceBadRequestError

${label} is required

Error message

${label} is required

What it means

normalizeEnumValue validates a labeled value against an allowed Set of strings. When the value is undefined, null, or whitespace-only and no fallback option is configured, it throws FlowSurfaceBadRequestError stating the field is required. Callers like inferQueryMode/inferVisualMode use it to resolve chart query/visual modes.

Source

Thrown at packages/plugins/@nocobase/plugin-flow-engine/src/server/flow-surfaces/chart-config.ts:482

  if (_.isUndefined(input) || _.isNull(input)) {
    return undefined;
  }
  return normalizeInteger(input, label, options);
}

function normalizeEnumValue(
  input: any,
  allowed: Set<string>,
  label: string,
  options: {
    fallback?: string;
  } = {},
) {
  if (_.isUndefined(input) || _.isNull(input) || String(input).trim() === '') {
    if (!_.isUndefined(options.fallback)) {
      return options.fallback;
    }
    throw new FlowSurfaceBadRequestError(`${label} is required`);
  }
  const normalized = String(input).trim();
  if (!allowed.has(normalized)) {
    throw new FlowSurfaceBadRequestError(`${label} is invalid: ${normalized}`);
  }
  return normalized;
}

function normalizeOptionalEnumValue(input: any, allowed: Set<string>, label: string) {
  if (_.isUndefined(input) || _.isNull(input) || String(input).trim() === '') {
    return undefined;
  }
  return normalizeEnumValue(input, allowed, label);
}

function normalizeFieldPathValue(input: any, label: string, options: { required?: boolean } = {}) {
  if (_.isUndefined(input) || _.isNull(input)) {
    if (options.required) {

View on GitHub (pinned to fa42722fef)

Solutions

  1. Set the field to one of the allowed values (check the surrounding schema/docs for valid modes, e.g. sql vs aggregation)
  2. Supply a non-empty string at the config source (env, JSON, form) so the value resolves
  3. If a default should apply, set the value explicitly to the intended default rather than leaving it blank

Example fix

// before
{ "queryMode": "" }
// after
{ "queryMode": "sql" }
Defensive patterns

Strategy: validation

Validate before calling

const QUERY_MODES = new Set(['sql','aggregation']);
if (!config.queryMode || !String(config.queryMode).trim()) {
  config.queryMode = 'sql'; // or throw in your own validation
}

Type guard

const isFilledEnum = (v: unknown, allowed: Set<string>): v is string => typeof v === 'string' && allowed.has(v.trim());

Try / catch

try { await submitChartConfig(cfg); } catch (e) { if (e instanceof FlowSurfaceBadRequestError && /is required$/.test(e.message)) { /* prompt user to select the missing mode field */ } else { throw e; } }

Prevention

When it happens

Trigger: Omitting a required enum field (e.g. query mode or visual type) in chart config where the specific normalizeEnumValue call has no fallback; passing '' or ' ' for such a field.

Common situations: Hand-written config missing newer required fields after an upgrade; form submit leaving a select empty; template rendering with a blank variable.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01). Data as JSON: /api/errors/0320e31cdddc352d. Report an issue: GitHub.