BoundaryML/baml · error · io::Error

no filesystem is attached to this server ({})

Error message

no filesystem is attached to this server ({})

What it means

NoFs::read_to_string always fails with an io::Error of kind Unsupported carrying 'no filesystem is attached to this server ({path})'. It exists so the LSP server can run purely from editor buffers with no disk access; any code path that tries to touch the disk while NoFs is installed triggers it.

Source

Thrown at baml_language/crates/baml_lsp/src/discovery.rs:123

            tracing::debug!(
                path = %toml_path.display(),
                %error,
                "unparseable manifest; the project stays unnamed"
            );
        })
        .ok()?;
    let name = manifest.package.as_ref()?.name.as_ref()?.trim();
    (!name.is_empty()).then(|| Name::new(name))
}

/// A filesystem-less host: reads fail with `Unsupported` and discovery finds
/// nothing. Documents are still served from their editor buffers.
#[derive(Debug, Default, Clone, Copy)]
pub struct NoFs;

impl ProjectFs for NoFs {
    fn read_to_string(&self, path: &Path) -> std::io::Result<String> {
        Err(std::io::Error::new(
            std::io::ErrorKind::Unsupported,
            format!(
                "no filesystem is attached to this server ({})",
                path.display()
            ),
        ))
    }

    fn discover_roots(&self, _folder: &Path) -> Vec<DiscoveredRoot> {
        Vec::new()
    }
}

/// The real filesystem, for native hosts.
#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug, Default, Clone, Copy)]
pub struct NativeFs;

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Attach a real filesystem implementation to the server instead of NoFs if disk access is intended
  2. Ensure the document is open in the editor (didOpen) so it is served from buffers
  3. Construct NoFs with a proper backing store for headless use (e.g. in-memory map)

Example fix

// before
let fs = NoFs; // server never reads from disk
let src = fs.read_to_string(&path)?;
// after (in-memory fallback)
match buffers.get(&path) {
    Some(src) => Ok(src.clone()),
    None => Err(io::Error::new(Unsupported, format!("{} not open in editor", path.display()))),
}
Defensive patterns

Strategy: validation

Validate before calling

if matches!(server.fs(), ProjectFs::NoFs) && !buffers.contains_key(&path) {
    return Err(format!("{} is not open in the editor", path.display()));
}

Type guard

fn has_real_fs(fs: &dyn ProjectFs) -> bool {
    fs.as_any().downcast_ref::<NoFs>().is_none()
}

Try / catch

match fs.read_to_string(&path) {
    Err(e) if e.kind() == std::io::ErrorKind::Unsupported => serve_from_buffers(&path),
    other => other,
}

Prevention

When it happens

Trigger: Project discovery or document loading calling ProjectFs::read_to_string on a server configured with NoFs (headless/no-filesystem mode); loading a file not present in any open editor buffer.

Common situations: Running the LSP in embedded/headless mode and requesting operations on unopened files; tests that forgot to attach a real or in-memory filesystem; the client never sent the file contents via didOpen.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/9dfbab10a9a49894. Report an issue: GitHub.