{"record":{"id":"2c9c78f3d1c1bc02","repo":"astral-sh/ruff","slug":"the-system-does-not-support-writing-files","errorCode":null,"errorMessage":"The system does not support writing files","messagePattern":"The system does not support writing files","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/ty_project/src/db.rs","lineNumber":668,"sourceCode":"        ty_vendored::file_system()\n    }\n\n    fn system(&self) -> &dyn System {\n        &*self.system\n    }\n\n    fn files(&self) -> &Files {\n        &self.files\n    }\n}\n\n#[salsa::db]\nimpl salsa::Database for ProjectDatabase {}\n\nimpl DbWithWritableSystem for ProjectDatabase {\n    fn writable_system(&self) -> ruff_db::system::Result<&dyn WritableSystem> {\n        self.system().as_writable().ok_or_else(|| {\n            std::io::Error::new(\n                std::io::ErrorKind::Unsupported,\n                \"The system does not support writing files\",\n            )\n        })\n    }\n}\n\n#[salsa::db]\nimpl Db for ProjectDatabase {\n    fn project(&self) -> Project {\n        self.project.unwrap()\n    }\n\n    fn uv_environments(&self) -> &UvEnvironments {\n        &self.uv_environments\n    }\n\n    fn dyn_clone(&self) -> Box<dyn Db> {","sourceCodeStart":650,"sourceCodeEnd":686,"githubUrl":"https://github.com/astral-sh/ruff/blob/15f3fe6b15a5f00172f34b0f542f8ea277f5a586/crates/ty_project/src/db.rs#L650-L686","documentation":"This is a Rust `std::io::Error` with `ErrorKind::Unsupported` produced by ty's `ProjectDatabase::writable_system()` when the underlying `System` does not implement the `WritableSystem` trait (`system().as_writable()` returns `None`). It surfaces when a caller (e.g. the ty server or `ty_python_semantic::fixes::fix_all`) attempts to write a file to disk, but the database was constructed with a read-only or virtual system that only supports reading. The library throws it to make write capability an explicit, checked property of the system abstraction instead of assuming writes always work.","triggerScenarios":"Calling any operation that goes through `DbWithWritableSystem::writable_system()` — such as applying code fixes (`fix_all`) that write files, or server write operations — while the `ProjectDatabase` was built over a system whose `as_writable()` returns `None` (e.g. the read-only test/memory system in `ruff_db::system::test`, or a custom read-only `System` implementation). The real `OsSystem` always returns `Some(self)`, so this only fires with non-OS systems.","commonSituations":"Running ty embedded in a tool or test harness that injects a virtual in-memory system for hermetic analysis; configuring the LSP server with a read-only system; implementing a custom `System` trait implementation without overriding `as_writable()` to return a writable adapter; calling fix/apply-diagnostics APIs in a read-only preview mode.","solutions":["Use a system that supports writing (e.g. `OsSystem`) when constructing the `ProjectDatabase` if you intend to write or apply fixes.","If using a custom `System`, implement `as_writable()` to return a `Some(&dyn WritableSystem)` adapter (see `crates/ruff_db/src/system/os.rs:195`).","Before calling write-dependent APIs (like `fix_all`), check writability up front via `db.system().as_writable().is_some()` and skip or surface a read-only message instead.","If you only need analysis without writes, avoid invoking write paths so the read-only system is never asked to write.","Keep the virtual/read-only system for tests but switch to `OsSystem` in production configuration."],"exampleFix":"// before: read-only (virtual) system injected, writes fail\nlet system: DynSystem = test::TestSystem::new().into();\nlet db = ProjectDatabase::new(module_db, system);\nfix_all(&mut db)?; // io::Error (Unsupported)\n\n// after: use a writable OS-backed system\nlet system: DynSystem = OsSystem::new(cwd).into();\nlet db = ProjectDatabase::new(module_db, system);\nfix_all(&mut db)?;","handlingStrategy":"validation","validationCode":"// Check writability before calling write-dependent APIs\nif db.system().as_writable().is_none() {\n    eprintln!(\"Operation skipped: this system does not support writing files\");\n    return Ok(());\n}","typeGuard":"fn is_writable(db: &dyn DbWithWritableSystem) -> bool {\n    db.system().as_writable().is_some()\n}","tryCatchPattern":"// Rust: match on the io::Error kind rather than any error\nmatch db.writable_system() {\n    Ok(system) => { /* use system to write */ }\n    Err(e) if e.kind() == std::io::ErrorKind::Unsupported => {\n        // read-only environment: degrade gracefully\n        eprintln!(\"Cannot write: system is read-only\");\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Construct ProjectDatabase with a writable system whenever fix/apply operations may run.","Expose a `--read-only` awareness in your tooling: disable fixers instead of letting them fail.","When implementing the `System` trait, always decide deliberately what `as_writable()` returns and test both branches.","Check `as_writable().is_some()` before offering fix-alls or write features in IDE/server integrations.","Keep write paths behind a capability check so read-only virtual systems used in tests never reach them."],"tags":["io","rust","read-only","unsupported","ty","write"],"backgroundTag":"file-write-failed","analyzedSha":"15f3fe6b15a5f00172f34b0f542f8ea277f5a586","analyzedAt":"2026-09-13T03:03:58.658Z","contentChangedAt":"2026-09-13T03:03:58.658Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}