Automattic/harper · error · anyhow::Error
Unable to save the dictionary to file: {err}
Error message
Unable to save the dictionary to file: {err} What it means
`save_user_dictionary` writes the user's mutable dictionary to the configured `user_dict_path` via `save_dict`. When the underlying file write fails (I/O error, missing directory, permissions), the error is wrapped with "Unable to save the dictionary to file" and propagated from the `execute_command` handler (e.g. add-word-to-dictionary).
Source
Thrown at harper-ls/src/backend.rs:162
.await
.context("Unable to save the dictionary to path.")
}
async fn load_user_dictionary(&self) -> MutableDictionary {
let config = self.config.read().await;
load_dict(&config.user_dict_path, self.config.read().await.dialect)
.await
.map_err(|err| info!("{err}"))
.unwrap_or(MutableDictionary::new())
}
async fn save_user_dictionary(&self, dict: impl Dictionary) -> Result<()> {
let config = self.config.read().await;
save_dict(&config.user_dict_path, dict)
.await
.map_err(|err| anyhow!("Unable to save the dictionary to file: {err}"))
}
async fn load_workspace_dictionary(&self) -> MutableDictionary {
let config = self.config.read().await;
load_dict(
&config.workspace_dict_path,
self.config.read().await.dialect,
)
.await
.map_err(|err| info!("{err}"))
.unwrap_or(MutableDictionary::new())
}
async fn save_workspace_dictionary(&self, dict: impl Dictionary) -> Result<()> {
let config = self.config.read().await;
save_dict(&config.workspace_dict_path, dict)
.await
.map_err(|err| anyhow!("Unable to save the dictionary to file: {err}"))View on GitHub (pinned to 5fe7d5ab76)
Solutions
- Create the parent directory of the configured user dict path and ensure it is writable.
- Check `user_dict_path` in your config points to a valid, writable file location.
- Fix filesystem permissions (or run outside a read-only mount/container).
- Verify disk space and that the path is not itself a directory.
Example fix
// before (config)
{ "userDictPath": "./missing-dir/user-dict.txt" }
// after
// mkdir missing-dir first, or point at an existing writable dir:
{ "userDictPath": "./user-dict.txt" } Defensive patterns
Strategy: try-catch
Validate before calling
import fs from 'node:fs';
const dir = path.dirname(userDictPath);
fs.mkdirSync(dir, { recursive: true });
fs.accessSync(dir, fs.constants.W_OK); Try / catch
try {
await client.sendRequest('workspace/executeCommand', { command: 'harperLs.addUserWord', arguments: [word] });
} catch (err) {
if (String(err.message).includes('Unable to save the dictionary to file')) {
// fix user_dict_path permissions/existence, then retry
}
} Prevention
- Pre-create the directory containing user_dict_path
- Point user_dict_path at a writable location (avoid read-only mounts/containers)
- Confirm the path is a file, not a directory
- Check disk space in CI/devcontainers
When it happens
Trigger: Calling the add-to-dictionary LSP command (or execute_command path) when `user_dict_path` points to a nonexistent directory, a read-only location, or a path the process cannot create/write.
Common situations: user_dict_path configured relative to a workspace root that doesn't exist; read-only home or container filesystem; parent directory deleted while the server runs; path points to a directory rather than a file.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Unable to convert URL to file path.
- Unable to convert URI to file path.
- Unable to convert URI to file path.
- Failed to load curated dictionary: {}
- The code action configuration must be an object.
AI-assisted analysis of Automattic/harper@5fe7d5ab76 (2026-09-06).
Data as JSON: /api/errors/7271124b179e4f48.
Report an issue: GitHub.