Hmbown/CodeWhale · error
Failed to write MCP config
Error message
Failed to write MCP config {}: {} What it means
Thrown by the MCP config save routine when creating the serialized JSON succeeded but the atomic write to disk failed. The message includes the target path and the underlying error from `crate::utils::write_atomic`.
Solutions
- Fix permissions: ensure your user can write the config file and its parent directory.
- Free disk space or resolve quota limits if the wrapped error indicates ENOSPC.
- Check whether the filesystem/mount is read-only and remount or choose another --config-path.
- Recreate a root-owned config as your user (`sudo chown $USER <path>`).
Example fix
// before sudo codewhale mcp enable my-server # may leave root-owned config // after codewhale mcp enable my-server # or repair once: sudo chown $USER: $(path to mcp.json)
Defensive patterns
Strategy: try-catch
Validate before calling
let probe = path.with_extension(".probe");
if std::fs::write(&probe, b"").is_err() {
eprintln!("no write access to config directory: {}", path.display());
}
let _ = std::fs::remove_file(&probe); Try / catch
match std::fs::write(&path, &rendered) {
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => eprintln!("chown/chmod the config: {}", path.display()),
Err(e) => eprintln!("write failed: {e}"),
Ok(_) => /* continue */,
} Prevention
- Check free disk space and quota before bulk config changes.
- Avoid sudo for MCP commands so the config stays user-owned.
- Confirm the target filesystem is writable (not a read-only mount).
When it happens
Trigger: save_mcp_config when write_atomic fails: no write permission on the file or its directory, directory was removed between create_dir_all and the write, read-only filesystem, disk full, or (for atomic rename semantics) cross-device or lock issues on the target path.
Common situations: Config file owned by root after a sudo run; read-only mount or container filesystem; disk quota exceeded; another process holding a conflicting lock; antivirus/backup tools briefly locking the file on Windows.
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
- Failed to read MCP config
- MCP config path must be a regular file
- Cannot resolve current binary path
- Codewhale credentials directory cannot be a volume root
- CODEWHALE_HOME / user home is unavailable
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/b377662aacb12e99.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/lib.rs:10323
valid_name(scope)
&& valid_name(package)
&& version.is_none_or(|value| {
!value.is_empty()
&& !value.contains(['@', '/', '\\'])
&& !value.chars().any(char::is_whitespace)
})
}
fn save_mcp_config(path: &Path, cfg: &McpConfig) -> Result<()> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).with_context(|| {
format!("Failed to create MCP config directory {}", parent.display())
})?;
}
let rendered = serde_json::to_string_pretty(cfg)
.map_err(|e| anyhow!("Failed to serialize MCP config: {e}"))?;
crate::utils::write_atomic(path, rendered.as_bytes())
.map_err(|e| anyhow!("Failed to write MCP config {}: {}", path.display(), e))?;
Ok(())
}
fn run_sandbox_command(args: SandboxArgs) -> Result<()> {
use crate::sandbox::{CommandSpec, SandboxManager};
let SandboxCommand::Run {
policy,
network,
writable_root,
exclude_tmpdir,
exclude_slash_tmp,
cwd,
timeout_ms,
command,
} = args.command;
let policy = parse_sandbox_policy(View on GitHub (pinned to 433685b202)