nocobase/nocobase · error · FlowSurfaceBadRequestError

FLOW_SURFACE_BAD_REQUEST

FLOW_SURFACE_BAD_REQUEST

Error message

flowSurfaces field container '${containerUse}' is not supported

What it means

While inferring a field's model 'use' from its interface, the field container kind (form, details, table, filter-form) is looked up in a switch; any containerUse outside these supported kinds reaches the default branch and throws. The library only supports field rendering inside those four container types.

Source

Thrown at packages/plugins/@nocobase/plugin-flow-engine/src/server/flow-surfaces/catalog.ts:3120

  if (
    shouldUseAssociationTitleTextDisplay({
      containerUse,
      fieldInterface,
    })
  ) {
    return 'DisplayTextFieldModel';
  }
  switch (normalizeFieldContainerUse(containerUse)) {
    case 'filter-form':
      return inferFilterFieldUse(fieldInterface);
    case 'form':
      return inferEditableFieldUse(fieldInterface);
    case 'details':
      return inferDisplayFieldUse(fieldInterface);
    case 'table':
      return inferDisplayFieldUse(fieldInterface);
    default:
      throw new FlowSurfaceBadRequestError(`flowSurfaces field container '${containerUse}' is not supported`);
  }
}

function inferJsFieldUseByContainer(containerUse?: string) {
  switch (normalizeFieldContainerUse(containerUse)) {
    case 'form':
      return 'JSEditableFieldModel';
    case 'details':
    case 'table':
      return 'JSFieldModel';
    case 'filter-form':
      throw new FlowSurfaceBadRequestError(`flowSurfaces field renderer 'js' is not allowed under '${containerUse}'`);
    default:
      throw new FlowSurfaceBadRequestError(`flowSurfaces field container '${containerUse}' is not supported`);
  }
}

function resolveStandaloneFieldUse(input: { requestedType?: string; containerUse?: string }) {

View on GitHub (pinned to fa42722fef)

Solutions

  1. Set containerUse to one of the supported values: 'form', 'details', 'table', or 'filter-form'
  2. Check for typos/pluralization in the container use string
  3. Place the field inside a supported container node instead of an unsupported custom container

Example fix

// before
resolveSupportedFieldCapability({ containerUse: 'forms' })
// after
resolveSupportedFieldCapability({ containerUse: 'form' })
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_FIELD_CONTAINERS = ['form', 'details', 'table', 'filter-form'];
if (!SUPPORTED_FIELD_CONTAINERS.includes(containerUse)) {
  throw new Error(`containerUse must be one of ${SUPPORTED_FIELD_CONTAINERS.join(', ')}`);
}

Type guard

function isSupportedFieldContainer(v) {
  return v === 'form' || v === 'details' || v === 'table' || v === 'filter-form';
}

Try / catch

try {
  resolveFieldCapability({ containerUse });
} catch (err) {
  if (err?.code === 'FLOW_SURFACE_BAD_REQUEST' && /field container .* is not supported/.test(err.message)) {
    // fall back to 'form' or surface a validation message to the user
  } else throw err;
}

Prevention

When it happens

Trigger: Resolving a field capability with a containerUse that is empty/garbled or not one of 'form' | 'details' | 'table' | 'filter-form' — e.g. a typo like 'forms' or 'grid', or a container node whose use is an unsupported model type.

Common situations: Typos in hand-written surface specs; custom container models that aren't yet mapped; passing the raw block uid instead of the container use; older specs written for a version with different container vocabulary.

Related errors


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