loco-rs/loco · error
fs service should build with success
Error message
fs service should build with success
What it means
Loco's local filesystem storage driver builds an OpenDAL `Operator` from a default `Fs` service rooted at ".". The `Fs` builder's validation (e.g. refusing an invalid or empty root path, or an incompatible option combination) can fail at `Operator::new`; since there is no sensible fallback, the code `.expect()`s and panics with this message.
Solutions
- Ensure the process's current working directory exists and is accessible before starting the app
- Pin/align the `opendal` version with what loco expects (0.58-style API) in Cargo.lock
- Configure a storage root explicitly via config `storage:` settings rather than relying on the `.` default
- If constructing manually in tests, chdir to a valid temp dir first (e.g. `std::env::set_current_dir` to a temp path)
Defensive patterns
Strategy: fallback
Validate before calling
// Ensure cwd is usable before building the local storage driver
let cwd = std::env::current_dir()?;
assert!(cwd.exists(), "current working directory {:?} missing", cwd);
let probe = std::fs::metadata(&cwd)?; Try / catch
// Local driver construction is infallible-by-panic; isolate it
let driver = std::panic::catch_unwind(loco_rs::storage::drivers::local::new)
.map_err(|_| anyhow::anyhow!("local storage failed to build; check cwd"))?; Prevention
- Never delete/replace the process working directory while running (careful with Docker layer tricks)
- Configure storage roots explicitly in config instead of relying on "."
- Keep opendal aligned with loco's expected version in Cargo.lock
When it happens
Trigger: Calling `loco_rs::storage::drivers::local::new()` when the OpenDAL `Fs` builder rejects its configuration — practically only when the default `.` root becomes invalid, e.g. the current working directory was deleted, or an OpenDAL version change altered builder validation.
Common situations: Running the server with its working directory removed (Docker images that delete then re-create cwd); mixing incompatible opendal versions after a dependency bump; constructing the driver in a broken test harness where cwd is unusable.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- memory service must build with success
- failed to install signal handler
- logger initialization failed
- create cleanup runtime
- db cleanup thread panicked
AI-assisted analysis of loco-rs/loco@23639d1e36 (2026-09-12).
Data as JSON: /api/errors/8175b91f06d0b4c9.
Report an issue: GitHub.
Appendix: source
Thrown at src/storage/drivers/local.rs:27
/// as `uploads/avatar.png` lands under the app directory rather than at the
/// filesystem root. To root the store elsewhere (including an absolute path),
/// use [`new_with_prefix`].
///
/// # Examples
///```
/// use loco_rs::storage::drivers::local;
/// let file_system_driver = local::new();
/// ```
///
/// # Panics
///
/// Panics if the filesystem service built failed.
#[must_use]
pub fn new() -> Box<dyn StoreDriver> {
let fs = Fs::default().root(".");
// opendal 0.58: Operator::new returns a finished Operator (no .finish()).
Box::new(OpendalAdapter::new(
Operator::new(fs).expect("fs service should build with success"),
))
}
/// Create new filesystem storage with `prefix` applied to all paths
///
/// # Examples
///```
/// use loco_rs::storage::drivers::local;
/// let file_system_driver = local::new_with_prefix("users");
/// ```
///
/// # Errors
///
/// Returns an error if the path does not exist
pub fn new_with_prefix(prefix: impl AsRef<std::path::Path>) -> StorageResult<Box<dyn StoreDriver>> {
let fs = Fs::default().root(&prefix.as_ref().display().to_string());
Ok(Box::new(OpendalAdapter::new(Operator::new(fs)?)))
}View on GitHub (pinned to 23639d1e36)