xai-org/grok-build · error · FsError

File not found

Error message

File not found

What it means

MockFileSystem is an in-memory FileSystem implementation backed by a HashMap of paths to bytes. read_file looks the path up in that map and, if absent, converts a std io::Error of kind NotFound with message 'File not found' into an FsError — mirroring a real filesystem's ENOENT.

Source

Thrown at crates/codegen/xai-grok-workspace/src/file_system/mock_fs.rs:29

}

#[async_trait::async_trait]
impl AsyncFileSystem for MockFs {
    fn root(&self) -> &Path {
        &self.root
    }

    async fn exists(&self, path: &Path) -> Result<bool, FsError> {
        let map = self.files.read().await;
        Ok(map.contains_key(path))
    }

    async fn read_file(&self, path: &Path) -> Result<Vec<u8>, FsError> {
        let map = self.files.read().await;
        if let Some(bytes) = map.get(path) {
            Ok(bytes.clone())
        } else {
            Err(io::Error::new(io::ErrorKind::NotFound, "File not found").into())
        }
    }

    async fn try_read_file(&self, path: &Path) -> Result<Option<Vec<u8>>, FsError> {
        let map = self.files.read().await;
        Ok(map.get(path).cloned())
    }

    async fn write_file(&self, path: &Path, data: &[u8]) -> Result<(), FsError> {
        let mut map = self.files.write().await;
        map.insert(path.to_path_buf(), data.to_vec());
        Ok(())
    }

    async fn delete_file(&self, path: &Path) -> Result<(), FsError> {
        let mut map = self.files.write().await;
        map.remove(path);
        Ok(())

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Insert the file into the mock before reading (call the mock's write_file/create API with the exact same Path).
  2. Normalize paths (absolute, canonical form) when writing and reading in tests.
  3. If the read is expected to sometimes miss, use try_read_file which returns Ok(None) instead of erroring.
  4. Fix the test path spelling/separator to match the key used at write time.

Example fix

// before
let data = fs.read_file(&Path::new("/tmp/a.txt")).await?; // never seeded
// after
fs.write_file(&Path::new("/tmp/a.txt"), b"hello").await?;
let data = fs.read_file(&Path::new("/tmp/a.txt")).await?;
Defensive patterns

Strategy: try-catch

Validate before calling

async fn mock_has(fs: &MockFileSystem, path: &Path) -> bool {
    fs.try_read_file(path).await.map(|o| o.is_some()).unwrap_or(false)
}
// seed or skip if false

Try / catch

match fs.read_file(&path).await {
    Ok(bytes) => bytes,
    Err(e) if matches!(&*e, FsError::Io(io) if io.kind() == std::io::ErrorKind::NotFound) => {
        Vec::new() // or seed and retry in test
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling read_file on a MockFileSystem for a path that was never inserted via the write/create API, or inserted under a different (non-identical) path — the map is keyed by exact Path, so separators, case, or a missing prefix cause a miss.

Common situations: Unit tests that forget to seed the mock before reading; tests writing with one path form (relative) and reading with another (absolute); typos or trailing separators in test paths; relying on a file another test was supposed to create.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/2e05942d6cd2fa35. Report an issue: GitHub.