{"record":{"id":"1c5f8e9d54ce4bb5","repo":"nocobase/nocobase","slug":"invalid-fieldname","errorCode":null,"errorMessage":"Invalid ${fieldName}","messagePattern":"Invalid (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugins/@nocobase/plugin-acl/src/server/actions/apply-data-permissions.ts","lineNumber":32,"sourceCode":"  name?: string;\n  fields?: string[];\n  scopeId?: number | null;\n  scopeKey?: string;\n  scope?: {\n    id?: number;\n    key?: string;\n  };\n}\n\ninterface ApplyResourceInput {\n  name?: string;\n  usingActionsConfig?: boolean;\n  actions?: ApplyActionInput[];\n}\n\nfunction ensureString(value: unknown, fieldName: string) {\n  if (typeof value !== 'string' || !value.trim()) {\n    throw new Error(`Invalid ${fieldName}`);\n  }\n  return value.trim();\n}\n\nfunction normalizeFields(fields: unknown): string[] | undefined {\n  if (!Array.isArray(fields)) {\n    return undefined;\n  }\n\n  const normalized = [\n    ...new Set(fields.filter((field): field is string => typeof field === 'string' && !!field.trim())),\n  ];\n  return normalized.length ? normalized : [];\n}\n\nfunction normalizeScopeId(scopeId: unknown): number | null | undefined {\n  if (scopeId === null) {\n    return null;","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/nocobase/nocobase/blob/fa42722fefe44265490dff2c27d79e2882bce4fa/packages/plugins/@nocobase/plugin-acl/src/server/actions/apply-data-permissions.ts#L14-L50","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the 400/error response and the request body; identify which <fieldName> is missing, empty, whitespace-only, or the wrong type.","Ensure the client always sends all required string fields: name, roleName, dataSourceKey, resourceName — trim and validate before submitting.","Convert numeric identifiers to strings (String(dataSourceKey)) before building the payload.","Add required/whitespace validation in the form or API client so invalid payloads never reach the server.","Update any integration tests/scripts constructing these payloads to include every required field."],"exampleFix":"// before\nawait request('roles', 'applyDataPermissions', { roleName: '', dataSourceKey: 1, resourceName: 'users' });\n// after\nawait request('roles', 'applyDataPermissions', {\n  roleName: roleName.trim(),\n  dataSourceKey: String(dataSourceKey),\n  resourceName: 'users',\n});","handlingStrategy":"validation","validationCode":"const required = { name, roleName, dataSourceKey, resourceName };\nfor (const [field, value] of Object.entries(required)) {\n  if (typeof value !== 'string' || !value.trim()) {\n    throw new TypeError(`Invalid ${field}`); // mirror server-side ensureString\n  }\n}","typeGuard":"function isNonEmptyString(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  await resource.applyDataPermissions(payload);\n} catch (err) {\n  if (err instanceof Error && /^Invalid (name|roleName|dataSourceKey|resourceName)$/.test(err.message)) {\n    // surface which field failed and prompt the user to fill it in\n    showFieldError(err.message.replace('Invalid ', ''));\n  } else throw err;\n}","preventionTips":["Validate all four required string fields client-side before submitting the request.","Convert numeric IDs (e.g. dataSourceKey) to strings before building payloads.","Add required + no-whitespace rules to permission forms so empty submissions are blocked.","Keep integration payloads in sync with the server's ensureString contract when upgrading."],"tags":["validation","acl","request-payload"],"backgroundTag":"invalid-request-parameter","analyzedSha":"fa42722fefe44265490dff2c27d79e2882bce4fa","analyzedAt":"2026-09-01T00:54:31.202Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}