{"record":{"id":"fd3e20086d5a61af","repo":"RocketChat/Rocket.Chat","slug":"the-setting-setting-id-is-not-readable","errorCode":null,"errorMessage":"The setting \"${setting.id}\" is not readable.","messagePattern":"The setting \"(.+?)\" is not readable\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/settings.ts","lineNumber":101,"sourceCode":"\n\t\tconst readSettings = readSettingsPermission as IReadSettingPermission;\n\t\t// If the setting is in the hiddenSettings list (defined within the permission), then it can bypass the hidden flag.\n\t\t// If not, then it must be a non-hidden setting. This is to allow apps to read hidden settings if they have the permission to do so.\n\t\tconst setting = readSettings.hiddenSettings?.includes(id) ? await Settings.findOneById(id) : await Settings.findOneNotHiddenById(id);\n\n\t\tif (!setting) {\n\t\t\tthis.orch.debugLog(`The setting ${id} is not found.`);\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.orch.getConverters()?.get('settings').convertToApp(setting);\n\t}\n\n\tprotected async updateOne(setting: ISetting & { id: string }, appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is updating the setting ${setting.id} .`);\n\n\t\tif (!(await this.isReadableById(setting.id, appId))) {\n\t\t\tthrow new Error(`The setting \"${setting.id}\" is not readable.`);\n\t\t}\n\n\t\tif (\n\t\t\t(\n\t\t\t\tawait updateAuditedByApp({\n\t\t\t\t\t_id: appId,\n\t\t\t\t})(Settings.updateValueById, setting.id, setting.value)\n\t\t\t).modifiedCount\n\t\t) {\n\t\t\tvoid notifyOnSettingChangedById(setting.id);\n\t\t}\n\t}\n\n\tprotected async incrementValue(id: string, value: number, appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is incrementing the value of the setting ${id}.`);\n\n\t\tif (!(await this.isReadableById(id, appId))) {\n\t\t\tthrow new Error(`The setting \"${id}\" is not readable.`);","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/app/apps/server/bridges/settings.ts#L83-L119","documentation":"Thrown by updateOne when the app attempts to modify a setting it is not allowed to read. The same isReadableById gate used by getOneById guards writes: if the setting is hidden/secret, missing, or outside the app's server-setting.read permission, the update is rejected before Settings.updateValueById runs.","triggerScenarios":"App calls updateOne with a setting id it has no read permission for, or for a setting that does not exist.","commonSituations":"App tries to write an admin-only or hidden setting without declaring the permission; setting was removed/renamed in a server version bump; app persists a cached setting id that is no longer valid.","solutions":["Declare server-setting.read (and the write permission your app needs) for the setting id in the app manifest.","Read the setting first to confirm it exists and is readable before updating.","Catch the error and inform the admin rather than leaving the app in a broken state."],"exampleFix":"// before\nawait modify.getSettings().updateOne({ id: 'My_Setting', value: 'x' });\n\n// after\n// app.json permissions include server-setting.read with 'My_Setting'\nconst readable = await read.getEnvironmentReader().getServerSettings().isReadableById('My_Setting');\nif (!readable) {\n  // handle gracefully\n  return;\n}\nawait modify.getSettings().updateOne({ id: 'My_Setting', value: 'x' });","handlingStrategy":"validation","validationCode":"const readable = await read.getEnvironmentReader().getServerSettings().isReadableById(setting.id);\nif (!readable) {\n  throw new Error(`Cannot update unreadable setting ${setting.id}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await modify.getSettings().updateOne({ id, value });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('is not readable')) {\n    // declare permission or pick a writable setting\n  } else {\n    throw err;\n  }\n}","preventionTips":["Declare server-setting.read for any id you intend to update.","Read the setting first to confirm it exists and is writable.","Notify the admin on failure rather than failing silently."],"tags":["apps-engine","settings","permissions","write","validation"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}