{"record":{"id":"d3c5823b5fd0d532","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-name","errorCode":"error-invalid-name","errorMessage":"Invalid name","messagePattern":"Invalid name","errorType":"http","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/lib/auth/oauth2-server/addOAuthApp.ts","lineNumber":27,"sourceCode":"\nexport async function addOAuthApp(applicationParams: OauthAppsAddParams, uid: IUser['_id'] | undefined): Promise<IOAuthApps> {\n\tif (!uid) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'addOAuthApp' });\n\t}\n\n\tconst user = await Users.findOneById(uid, { projection: { username: 1 } });\n\n\tif (!user?.username) {\n\t\t// TODO: username is required, but not always present\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'addOAuthApp' });\n\t}\n\n\tif (!(await hasPermissionAsync(uid, 'manage-oauth-apps'))) {\n\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'addOAuthApp' });\n\t}\n\n\tif (!applicationParams.name || typeof applicationParams.name.valueOf() !== 'string' || applicationParams.name.trim() === '') {\n\t\tthrow new Meteor.Error('error-invalid-name', 'Invalid name', { method: 'addOAuthApp' });\n\t}\n\n\tif (\n\t\t!applicationParams.redirectUri ||\n\t\ttypeof applicationParams.redirectUri.valueOf() !== 'string' ||\n\t\tapplicationParams.redirectUri.trim() === ''\n\t) {\n\t\tthrow new Meteor.Error('error-invalid-redirectUri', 'Invalid redirectUri', {\n\t\t\tmethod: 'addOAuthApp',\n\t\t});\n\t}\n\n\tif (typeof applicationParams.active !== 'boolean') {\n\t\tthrow new Meteor.Error('error-invalid-arguments', 'Invalid arguments', {\n\t\t\tmethod: 'addOAuthApp',\n\t\t});\n\t}\n","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/auth/oauth2-server/addOAuthApp.ts#L9-L45","documentation":"First content validation inside addOAuthApp: applicationParams.name must exist, be a string (checked via typeof valueOf()), and not trim to an empty string. The REST layer's ajv schema already requires a string, so in practice the trim check is what fires (whitespace-only names pass ajv but fail here); a missing or non-string name only reaches this line from direct/internal calls.","triggerScenarios":"POST /api/v1/oauth-apps.create with body { name: '   ', active: true, redirectUri: '...' }; a direct addOAuthApp call omitting name or passing a number/object; form inputs submitted after the user cleared the field but left spaces.","commonSituations":"UI forms not trimming inputs; scripts posting placeholder values; client-side joins producing whitespace strings.","solutions":["Send a non-empty, meaningful application name","Trim inputs client-side before submitting (name.trim() !== '')","For direct calls, validate params with the same OauthAppsAddParams shape the REST schema enforces"],"exampleFix":"// before\n{ \"name\": \"   \", \"active\": true, \"redirectUri\": \"https://app.example.com/cb\" }\n\n// after\n{ \"name\": \"My Integration\", \"active\": true, \"redirectUri\": \"https://app.example.com/cb\" }","handlingStrategy":"type-guard","validationCode":"// client-side, before POST /api/v1/oauth-apps.create\nconst name = String(form.name ?? '').trim();\nif (!name) throw new Error('Application name is required');\nawait post('/oauth-apps.create', { ...form, name });","typeGuard":"const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;\n\nconst isValidAppParams = (p: unknown): p is { name: string; active: boolean; redirectUri: string } =>\n  typeof p === 'object' && p !== null && isNonEmptyString((p as any).name) && isNonEmptyString((p as any).redirectUri) && typeof (p as any).active === 'boolean';","tryCatchPattern":"try {\n  await addOAuthApp(params, uid);\n} catch (error) {\n  if (error instanceof Meteor.Error && error.error === 'error-invalid-name') {\n    setFieldError('name', 'Enter a non-empty application name');\n  } else {\n    throw error;\n  }\n}","preventionTips":["Trim form inputs client-side","Validate with the same shape the REST schema requires before submitting","Disable the submit button until required fields are non-empty"],"tags":["oauth-apps","validation","rest-api","input-validation"],"backgroundTag":"api-request-validation-failed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}