Automattic/harper · warning
ForceStable must be a boolean value.
Error message
ForceStable must be a boolean value.
What it means
Type-validation failure raised in CodeActionConfig::from_lsp_config when the "ForceStable" key in the submitted LSP configuration JSON exists but is not a JSON boolean (e.g. the string "true" or the number 1). from_lsp_config only reads ForceStable when the key is present, so this fires solely because of a malformed value type, not a missing key. The field controls whether harper-ls sorts unstable code actions (like dictionary additions) last. Fix: set "ForceStable" to true or false in the client's harper-ls settings, or remove the key to use the default.
Source
Thrown at harper-ls/src/config.rs:56
/// Instructs `harper-ls` to place unstable code actions last.
/// In this case, "unstable" refers to their existence and action.
///
/// For example, we always want to allow users to add "misspelled" elements
/// to dictionary, regardless of the spelling suggestions.
pub force_stable: bool,
}
impl CodeActionConfig {
pub fn from_lsp_config(value: Value) -> Result<Self> {
let mut base = CodeActionConfig::default();
let Value::Object(value) = value else {
bail!("The code action configuration must be an object.");
};
if let Some(force_stable_val) = value.get("ForceStable") {
let Value::Bool(force_stable) = force_stable_val else {
bail!("ForceStable must be a boolean value.");
};
base.force_stable = *force_stable;
};
Ok(base)
}
}
#[derive(Debug, Clone)]
pub struct Config {
pub user_dict_path: PathBuf,
pub file_dict_path: PathBuf,
pub workspace_dict_path: PathBuf,
pub ignored_lints_path: PathBuf,
pub stats_path: PathBuf,
pub lint_config: FlatConfig,
pub diagnostic_severity: DiagnosticSeverity,
pub code_action_config: CodeActionConfig,View on GitHub (pinned to 5fe7d5ab76)
Solutions
- Change the value to a real JSON boolean: "ForceStable": true.
- Remove the ForceStable key entirely to accept the default.
- Check your editor's settings file for accidental string quoting around true/false.
Example fix
// before
"codeAction": { "ForceStable": "true" }
// after
"codeAction": { "ForceStable": true } Defensive patterns
Strategy: validation
Validate before calling
const forceStable = settings?.harperLs?.codeAction?.forceStable;
if (forceStable !== undefined && typeof forceStable !== 'boolean') {
throw new TypeError('ForceStable must be a boolean');
} Type guard
fn is_bool(v: &serde_json::Value) -> bool { v.is_boolean() } Try / catch
match CodeActionConfig::from_lsp_config(value) {
Ok(cfg) => cfg,
Err(e) => { log::warn!("bad codeAction config: {e}"); CodeActionConfig::default() }
} Prevention
- Write booleans unquoted in JSON settings (true, not "true").
- Use editor setting definitions with a boolean type so the UI enforces the type.
- Validate settings payloads before sending them to the server.
When it happens
Trigger: Sending codeAction settings containing `"ForceStable": "true"` (string), 1, or null to harper-ls via didChangeConfiguration/initialize options.
Common situations: Typing the setting without quotes-as-boolean in JSON (JSON has no bare true fallback when quoted), YAML/JSON5 configs where unquoted true got serialized as a string, editor plugins that pass settings through unvalidated.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- The code action configuration must be an object.
- Settings must be an object.
- userDict path must be a string.
- Settings must contain a "harper-ls" key.
- fileDict path must be a string.
AI-assisted analysis of Automattic/harper@5fe7d5ab76 (2026-09-06).
Data as JSON: /api/errors/3f391f881e047bcc.
Report an issue: GitHub.