{"record":{"id":"bc0135fd7856504b","repo":"RocketChat/Rocket.Chat","slug":"error-name-param-not-provided","errorCode":"error-name-param-not-provided","errorMessage":"The parameter \"name\" is required","messagePattern":"The parameter \"name\" is required","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/settings.ts","lineNumber":254,"sourceCode":"\t\t\tPOST: { permissions: ['add-oauth-service'], operation: 'hasAll' },\n\t\t},\n\t\tbody: addCustomOAuthBodySchema,\n\t\tresponse: {\n\t\t\t200: ajv.compile<void>({\n\t\t\t\ttype: 'object',\n\t\t\t\tproperties: { success: { type: 'boolean', enum: [true] } },\n\t\t\t\trequired: ['success'],\n\t\t\t\tadditionalProperties: false,\n\t\t\t}),\n\t\t\t400: validateBadRequestErrorResponse,\n\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t\t403: validateForbiddenErrorResponse,\n\t\t},\n\t},\n\tasync function action() {\n\t\tconst { name } = this.bodyParams;\n\t\tif (!name?.trim()) {\n\t\t\tthrow new Meteor.Error('error-name-param-not-provided', 'The parameter \"name\" is required');\n\t\t}\n\n\t\tawait addOAuthServiceMethod(this.userId, name);\n\n\t\treturn API.v1.success();\n\t},\n);\n\nAPI.v1.post(\n\t'settings.removeCustomOAuth',\n\t{\n\t\tauthRequired: true,\n\t\ttwoFactorRequired: true,\n\t\tpermissionsRequired: {\n\t\t\tPOST: { permissions: ['add-oauth-service'], operation: 'hasAll' },\n\t\t},\n\t\tbody: addCustomOAuthBodySchema,\n\t\tresponse: {","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/2a7de457074cbb4d4373fbd9a4e5bea292c9c764/apps/meteor/server/api/v1/settings.ts#L236-L272","documentation":"Thrown by POST settings.addCustomOAuth when the request body has no usable \"name\" field (missing, empty, or whitespace-only). The route registers a new custom OAuth provider and needs the provider name to build its setting group. It is admin-only (add-oauth-service permission) and protected by two-factor authentication, but the name check runs before any of that business logic.","triggerScenarios":"POST /api/v1/settings.addCustomOAuth with body {}, {\"name\": \"\"}, or {\"name\": \"   \"}; sending the field under a different key (serviceName, provider); sending JSON without Content-Type: application/json so bodyParams ends up empty.","commonSituations":"Automation scripts that template the OAuth provider name from an empty variable; clients porting from the old addOAuthService method call that used a different payload shape; CI provisioning that runs before the config file with provider names is loaded.","solutions":["Send a non-empty trimmed name: {\"name\": \"github-enterprise\"} with Content-Type: application/json","If the body looks correct, verify it is actually parsed: no form-encoding mixups, no trailing commas, valid JSON","Check for key typos — only \"name\" is read from bodyParams","Remember the route also requires the add-oauth-service permission and an X-2FA-Code header; fix the name first since this error fires before those checks complete"],"exampleFix":"// before\nawait sdk.post('settings.addCustomOAuth', { serviceName: 'custom-saml' });\n// after\nawait sdk.post('settings.addCustomOAuth', { name: 'custom-saml' });","handlingStrategy":"validation","validationCode":"const name = typeof body?.name === 'string' ? body.name.trim() : '';\nif (!name) throw new Error('settings.addCustomOAuth requires a non-empty \"name\"');\nawait sdk.post('settings.addCustomOAuth', { name });","typeGuard":"const isNonEmptyName = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":"catch (e) { if (e?.error === 'error-name-param-not-provided') fixBodyName(); else throw e; }","preventionTips":["Validate required body fields before every call in a shared client wrapper","Send JSON with Content-Type: application/json so bodyParams is populated","Fail fast on empty config values in provisioning scripts instead of letting the API reject them"],"tags":["rest-api","validation","oauth","settings","admin"],"backgroundTag":"missing-required-argument","analyzedSha":"2a7de457074cbb4d4373fbd9a4e5bea292c9c764","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}