RocketChat/Rocket.Chat · error · Error
The setting "${setting.id}" is not readable.
Error message
The setting "${setting.id}" is not readable. What it means
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.
Source
Thrown at apps/meteor/app/apps/server/bridges/settings.ts:101
const readSettings = readSettingsPermission as IReadSettingPermission;
// If the setting is in the hiddenSettings list (defined within the permission), then it can bypass the hidden flag.
// 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.
const setting = readSettings.hiddenSettings?.includes(id) ? await Settings.findOneById(id) : await Settings.findOneNotHiddenById(id);
if (!setting) {
this.orch.debugLog(`The setting ${id} is not found.`);
return null;
}
return this.orch.getConverters()?.get('settings').convertToApp(setting);
}
protected async updateOne(setting: ISetting & { id: string }, appId: string): Promise<void> {
this.orch.debugLog(`The App ${appId} is updating the setting ${setting.id} .`);
if (!(await this.isReadableById(setting.id, appId))) {
throw new Error(`The setting "${setting.id}" is not readable.`);
}
if (
(
await updateAuditedByApp({
_id: appId,
})(Settings.updateValueById, setting.id, setting.value)
).modifiedCount
) {
void notifyOnSettingChangedById(setting.id);
}
}
protected async incrementValue(id: string, value: number, appId: string): Promise<void> {
this.orch.debugLog(`The App ${appId} is incrementing the value of the setting ${id}.`);
if (!(await this.isReadableById(id, appId))) {
throw new Error(`The setting "${id}" is not readable.`);View on GitHub (pinned to f9d3ec372b)
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.
Example fix
// before
await modify.getSettings().updateOne({ id: 'My_Setting', value: 'x' });
// after
// app.json permissions include server-setting.read with 'My_Setting'
const readable = await read.getEnvironmentReader().getServerSettings().isReadableById('My_Setting');
if (!readable) {
// handle gracefully
return;
}
await modify.getSettings().updateOne({ id: 'My_Setting', value: 'x' }); Defensive patterns
Strategy: validation
Validate before calling
const readable = await read.getEnvironmentReader().getServerSettings().isReadableById(setting.id);
if (!readable) {
throw new Error(`Cannot update unreadable setting ${setting.id}`);
} Try / catch
try {
await modify.getSettings().updateOne({ id, value });
} catch (err) {
if (err instanceof Error && err.message.includes('is not readable')) {
// declare permission or pick a writable setting
} else {
throw err;
}
} Prevention
- 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.
When it happens
Trigger: App calls updateOne with a setting id it has no read permission for, or for a setting that does not exist.
Common situations: 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.
Related errors
- The setting "${id}" is not readable.
- Invalid Api parameter provided, it must be a valid IApi obje
- Invalid command parameter provided, must be a string.
- Invalid Slash Command parameter provided, it must be a valid
- The environmental variable "${envVarName}" is not readable.
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/fd3e20086d5a61af.
Report an issue: GitHub.