nocobase/nocobase · error · Error

Invalid ${fieldName}

Error message

Invalid ${fieldName}

What it means

ensureString() is a helper in the ACL apply-data-permissions action that validates string parameters (name, roleName, dataSourceKey, resourceName) before use. A value must be a string with non-whitespace content; otherwise the server rejects the request with 'Invalid <fieldName>'. This prevents blank or wrongly-typed identifiers from reaching permission-application logic, where an empty role or resource name would silently create broken permission records.

Source

Thrown at packages/plugins/@nocobase/plugin-acl/src/server/actions/apply-data-permissions.ts:32

  name?: string;
  fields?: string[];
  scopeId?: number | null;
  scopeKey?: string;
  scope?: {
    id?: number;
    key?: string;
  };
}

interface ApplyResourceInput {
  name?: string;
  usingActionsConfig?: boolean;
  actions?: ApplyActionInput[];
}

function ensureString(value: unknown, fieldName: string) {
  if (typeof value !== 'string' || !value.trim()) {
    throw new Error(`Invalid ${fieldName}`);
  }
  return value.trim();
}

function normalizeFields(fields: unknown): string[] | undefined {
  if (!Array.isArray(fields)) {
    return undefined;
  }

  const normalized = [
    ...new Set(fields.filter((field): field is string => typeof field === 'string' && !!field.trim())),
  ];
  return normalized.length ? normalized : [];
}

function normalizeScopeId(scopeId: unknown): number | null | undefined {
  if (scopeId === null) {
    return null;

View on GitHub (pinned to fa42722fef)

Solutions

  1. Inspect the 400/error response and the request body; identify which <fieldName> is missing, empty, whitespace-only, or the wrong type.
  2. Ensure the client always sends all required string fields: name, roleName, dataSourceKey, resourceName — trim and validate before submitting.
  3. Convert numeric identifiers to strings (String(dataSourceKey)) before building the payload.
  4. Add required/whitespace validation in the form or API client so invalid payloads never reach the server.
  5. Update any integration tests/scripts constructing these payloads to include every required field.

Example fix

// before
await request('roles', 'applyDataPermissions', { roleName: '', dataSourceKey: 1, resourceName: 'users' });
// after
await request('roles', 'applyDataPermissions', {
  roleName: roleName.trim(),
  dataSourceKey: String(dataSourceKey),
  resourceName: 'users',
});
Defensive patterns

Strategy: validation

Validate before calling

const required = { name, roleName, dataSourceKey, resourceName };
for (const [field, value] of Object.entries(required)) {
  if (typeof value !== 'string' || !value.trim()) {
    throw new TypeError(`Invalid ${field}`); // mirror server-side ensureString
  }
}

Type guard

function isNonEmptyString(v: unknown): v is string {
  return typeof v === 'string' && v.trim().length > 0;
}

Try / catch

try {
  await resource.applyDataPermissions(payload);
} catch (err) {
  if (err instanceof Error && /^Invalid (name|roleName|dataSourceKey|resourceName)$/.test(err.message)) {
    // surface which field failed and prompt the user to fill it in
    showFieldError(err.message.replace('Invalid ', ''));
  } else throw err;
}

Prevention

When it happens

Trigger: POSTing to the apply-data-permissions action with roleName missing or empty ('' or ' '), dataSourceKey passed as a number instead of a string, resourceName omitted from the payload, or name supplied as null/undefined in the request body.

Common situations: Frontend form submitting the permission dialog before fields are filled; client code sending numeric data source keys (e.g. 1 instead of 'main'); API integrations (scripts/tests) constructing the payload manually and omitting required fields; whitespace-only input slipping past simple required-field checks.

Related errors


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