BoundaryML/baml · error · io::Error
{}: {error}
Error message
{}: {error} What it means
read_to_string in the WASM VFS reads a file via vfs_read_file and maps any backend error to io::Error::other('{path}: {error:?}'); it then separately maps UTF-8 decode failures to InvalidData '{path}: {error}'. So this message means either the virtual file could not be read (backend error string appended) or its bytes are not valid UTF-8.
Source
Thrown at baml_language/crates/bridge_wasm/src/wasm_vfs.rs:259
frontier.push(child);
} else if child.extension().is_some_and(|ext| ext == "baml") {
files.push(child);
}
}
}
files.sort();
files
}
}
impl ProjectFs for WasmProjectFs {
fn read_to_string(&self, path: &Path) -> std::io::Result<String> {
let bytes = self
.vfs()
.vfs_read_file(&path.to_string_lossy())
.map_err(|error| std::io::Error::other(format!("{}: {error:?}", path.display())))?;
String::from_utf8(bytes.to_vec()).map_err(|error| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("{}: {error}", path.display()),
)
})
}
fn discover_roots(&self, folder: &Path) -> Vec<DiscoveredRoot> {
let mut roots = Vec::new();
// The folder itself may sit inside a project (the host opened
// `baml_src/`, or a subdirectory of it).
roots.extend(
baml_db::project_resolution::find_baml_project_root_from_ancestors(
folder.ancestors().map(Path::to_path_buf),
|dir| self.is_file(&dir.join(baml_db::project_resolution::BAML_TOML)),
|dir| self.is_dir(&dir.join(baml_db::project_resolution::BAML_SRC_DIR)),
),
);
roots.extend(self.marked_roots(folder));View on GitHub (pinned to bd85ce9dee)
Solutions
- Verify the path exists in the VFS (write/upload it) before reading
- Use a bytes/read_file API for binary content and only call read_to_string for UTF-8 text
- Log the mapped error's trailing backend message to identify the underlying vfs_read_file failure
- Normalize the path (absolute, no duplicate slashes) as the VFS keys on exact strings
Example fix
// before
const text = vfs.read_to_string('/assets/logo.png'); // InvalidData
// after
const bytes = vfs.read_file('/assets/logo.png');
const text = isTextual(path) ? new TextDecoder().decode(bytes) : null; Defensive patterns
Strategy: try-catch
Validate before calling
function fileExistsInVfs(vfs, path) {
return vfs.vfs_list_dir(dirname(path)).includes(basename(path));
} Type guard
function isVfsReadError(e) {
return e instanceof Error && /: /.test(e.message) && (e.name === 'Error' || e.name === 'NotFoundError' || e.name === 'InvalidData');
} Try / catch
try {
text = vfs.read_to_string(path);
} catch (e) {
if (String(e.message).includes('stream did not contain valid UTF-8')) {
const bytes = vfs.vfs_read_file(path); // handle as binary
} else {
throw new Error(`VFS read failed for ${path}: ${e.message}`);
}
} Prevention
- Register every file in the VFS before reading it
- Only call read_to_string on known-textual paths
- Use a bytes API for binary assets
- Normalize paths to the exact string form the VFS keys on
When it happens
Trigger: Calling read_to_string on a path missing from the in-memory VFS, a backend I/O failure, or on binary (non-UTF-8) files that must not be read as strings.
Common situations: Loading BAML sources from a browser-injected VFS where the file was never registered, or accidentally reading .bmx/binary assets with read_to_string instead of a bytes API.
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
- WASM history boundary {} was not begun
- WASM history boundary {} was not found
- diagnostic message style code is a valid Unicode variation s
- no filesystem is attached to this server ({})
- native path is not valid Unicode: {0:?}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/67d43937e17201d3.
Report an issue: GitHub.