{"record":{"id":"0ca70372b73b256a","repo":"RocketChat/Rocket.Chat","slug":"error-id-param-not-provided","errorCode":"error-id-param-not-provided","errorMessage":"The parameter \"id\" is required","messagePattern":"The parameter \"id\" is required","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/settings.ts","lineNumber":406,"sourceCode":"\t'settings/:_id',\n\t{\n\t\tauthRequired: true,\n\t\tpermissionsRequired: {\n\t\t\tPOST: { permissions: ['edit-privileged-setting'], operation: 'hasAll' },\n\t\t},\n\t\ttwoFactorRequired: true,\n\t\tbody: settingsUpdateBodySchema,\n\t\tresponse: {\n\t\t\t200: settingByIdPostResponseSchema,\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 { _id } = this.urlParams;\n\t\tif (typeof _id !== 'string') {\n\t\t\tthrow new Meteor.Error('error-id-param-not-provided', 'The parameter \"id\" is required');\n\t\t}\n\n\t\tif (disableCustomScripts() && /^Custom_Script_/.test(_id)) {\n\t\t\treturn API.v1.forbidden('Custom scripts are disabled');\n\t\t}\n\n\t\tconst setting = await Settings.findOneNotHiddenById(_id);\n\n\t\tif (!setting) {\n\t\t\treturn API.v1.failure();\n\t\t}\n\n\t\tconst { bodyParams } = this;\n\n\t\tif (\n\t\t\tisSettingAction(setting) &&\n\t\t\tisSettingsUpdatePropsActions(bodyParams) &&\n\t\t\tbodyParams.execute &&","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/settings.ts#L388-L424","documentation":"Thrown by POST settings/:_id when the URL _id is not a string — i.e. it was not supplied at all. The route updates a single setting by id; the urlParams._id must be present in the path. Also note: ids matching /^Custom_Script_/ are blocked separately when disableCustomScripts is on.","triggerScenarios":"POST /api/v1/settings/<_id> where the <_id> path segment is missing so urlParams._id is undefined (not a string).","commonSituations":"Client building the URL with an undefined variable; calling the base /settings without an id; double slash collapsing the segment out.","solutions":["Ensure the setting _id is in the URL path: /api/v1/settings/LDAP_Enable.","Read existing setting ids from settings GET before posting.","URL-encode the id (some ids contain dots/underscores but are otherwise safe)."],"exampleFix":"// before\nawait rest.post(`/api/v1/settings/${undefined}`, { value: true });\n\n// after\nif (typeof settingId !== 'string' || !settingId) throw new Error('setting id required');\nawait rest.post(`/api/v1/settings/${encodeURIComponent(settingId)}`, { value: true });","handlingStrategy":"type-guard","validationCode":"if (typeof settingId !== 'string' || settingId.trim() === '') {\n  throw new Error('setting id is required in the URL path');\n}\nawait rest.post(`/api/v1/settings/${encodeURIComponent(settingId)}`, { value });","typeGuard":"function isSettingId(x: unknown): x is string {\n  return typeof x === 'string' && x.trim().length > 0;\n}","tryCatchPattern":"try {\n  await rest.post(`/api/v1/settings/${settingId}`, body);\n} catch (e) {\n  if (isMeteorError(e, 'error-id-param-not-provided')) {\n    notify('Setting id missing in URL.');\n  } else throw e;\n}","preventionTips":["Always template the _id into the path.","Guard against undefined before building the URL.","URL-encode the id."],"tags":["settings","validation","rest-api","admin"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}