pydantic/monty · error
host_read_bytes should return bytes
Error message
host_read_bytes should return bytes
What it means
An `unreachable!()` panic in monty-fs's overlay filesystem: `host_read_bytes` is contractually expected to return `MontyObject::Bytes`, and any other variant means the host read path violated its return-type contract. This is an internal consistency check in overlay file reads (used by `append_bytes` via `existing_file_bytes`).
Source
Thrown at crates/monty-fs/src/overlay.rs:581
/// Loads the current visible file content for append operations.
fn existing_file_bytes(
state: &OverlayState,
relative: &str,
ctx: &MountContext<'_>,
vpath: &str,
budget: MemoryBudget,
) -> Result<Vec<u8>, MountError> {
match state.get(relative) {
Some(OverlayEntry::File(file)) => {
budget.check(as_u64(file.content.len()))?;
Ok(file.content.clone())
}
Some(OverlayEntry::Deleted) => Ok(Vec::new()),
Some(OverlayEntry::RealFileRef(file_ref)) => {
let rel = checked_ref_path(file_ref, ctx, vpath)?;
match host_read_bytes(ctx.mount_dir, rel, vpath, budget)? {
MontyObject::Bytes(bytes) => Ok(bytes),
_ => unreachable!("host_read_bytes should return bytes"),
}
}
Some(OverlayEntry::Directory { .. }) => {
Err(MountError::io_err(ErrorKind::IsADirectory, "Is a directory", vpath))
}
None => match resolve_real_path_state(vpath, ctx, OnLookupFailure::Propagate)? {
RealPathState::Present(rel) => match host_read_bytes(ctx.mount_dir, &rel, vpath, budget)? {
MontyObject::Bytes(bytes) => Ok(bytes),
_ => unreachable!("host_read_bytes should return bytes"),
},
RealPathState::Missing => Ok(Vec::new()),
},
}
}
/// Rejects writes when the target path is an existing directory or a symlink.
///
/// On real filesystems, writing to a directory returns `EISDIR`; the overlayView on GitHub (pinned to adc986b362)
Solutions
- Inspect `host_read_bytes` and each mount backend to find where a non-Bytes MontyObject can be returned.
- Ensure the read path always wraps file contents in `MontyObject::Bytes`.
- Add/extend monty-fs integration tests covering RealFileRef overlay reads for all mount modes.
Example fix
// before (in host_read_bytes) Ok(MontyObject::Str(contents)) // after Ok(MontyObject::Bytes(contents.into_bytes()))
Defensive patterns
Strategy: type-guard
Validate before calling
// Contract check before consuming the read result: // assert every host_read_bytes return site constructs MontyObject::Bytes.
Type guard
fn as_bytes(obj: MontyObject) -> Option<Vec<u8>> {
match obj { MontyObject::Bytes(b) => Some(b), _ => None }
} Try / catch
match host_read_bytes(ctx.mount_dir, rel, vpath, budget)? {
MontyObject::Bytes(bytes) => Ok(bytes),
other => Err(MountError::internal(format!("host_read_bytes returned {other:?}, expected bytes"))),
} Prevention
- Keep host_read_bytes' return type narrowly Bytes and enforce it in every mount backend.
- Add overlay RealFileRef read tests for ReadWrite, ReadOnly, and OverlayMemory modes.
- Avoid widening the return type to MontyObject without updating all consumers.
When it happens
Trigger: Reading an overlay `RealFileRef` entry's bytes via `host_read_bytes` when it returns a non-Bytes `MontyObject` (e.g. Str or None) — only possible if the host read implementation or mount backend changed its return contract.
Common situations: Hit by Monty-fs contributors changing `host_read_bytes`, its backends (ReadWrite/ReadOnly mounts), or the MontyObject conversion at the mount boundary.
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
- non-filesystem OS function reached filesystem parser
- dict_keys view must reference a dict
- dict_items view must always reference a dict
- dict_items view must reference a dict
- dict_values view must always reference a dict
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/9ef815c1547f6fe2.
Report an issue: GitHub.