kitao/pyxel · error
Failed to read file '{path}'
Error message
Failed to read file '{path}' What it means
`parse_tmx` opened the TMX file but `read_to_string` failed, returning this error. This almost always means the file contains invalid UTF-8 (TMX should be UTF-8 XML) or an I/O error occurred mid-read. The io::Error detail is discarded, only the path is shown.
Source
Thrown at crates/pyxel-core/src/tmx_parser.rs:57
struct TmxMap {
#[serde(rename = "@tilewidth")]
tilewidth: u32,
#[serde(rename = "@tileheight")]
tileheight: u32,
#[serde(rename = "tileset", default)]
tilesets: Vec<Tileset>,
#[serde(rename = "layer", default)]
layers: Vec<Layer>,
}
pub fn parse_tmx(path: &str, layer_index: u32) -> Result<RcTilemap, String> {
let err = |msg| format!("{msg} '{path}'");
// Load and validate the TMX layer.
let mut file = File::open(path).map_err(|_| err("Failed to open file"))?;
let mut tmx_text = String::new();
file.read_to_string(&mut tmx_text)
.map_err(|_| err("Failed to read file"))?;
let tmx: TmxMap = serde_xml_rs::from_str(&tmx_text).map_err(|_| err("Failed to parse file"))?;
if tmx.tilewidth != TILE_SIZE || tmx.tileheight != TILE_SIZE {
return Err(err("Invalid tile size in file"));
}
let tileset = tmx
.tilesets
.first()
.ok_or_else(|| err("No tileset found in file"))?;
let columns = tileset
.columns
.ok_or_else(|| err("No embedded tileset in file"))?;
let layer = tmx
.layers
.get(layer_index as usize)View on GitHub (pinned to 50f9bd7778)
Solutions
- Re-export or re-save the TMX file as UTF-8 encoding from Tiled/your editor.
- Verify the file is actually XML text, not binary (open in an editor / `file` command).
- Re-download or restore the file if corrupted or truncated.
- If on a network drive, copy the file locally and retry.
Example fix
// before (file saved as UTF-16)
let tilemap = Tilemap::from_tmx("level.tmx", 0)?; // Failed to read file 'level.tmx'
// after: re-save with encoding=UTF-8 in Tiled preferences, then retry
let tilemap = Tilemap::from_tmx("level.tmx", 0)?; Defensive patterns
Strategy: validation
Validate before calling
// Verify the file is valid UTF-8 text before parse_tmx
fn tmx_is_utf8(path: &str) -> Result<(), String> {
let bytes = std::fs::read(path).map_err(|e| e.to_string())?;
std::str::from_utf8(&bytes)
.map(|_| ())
.map_err(|_| format!("{} is not valid UTF-8; re-save TMX as UTF-8", path))
} Try / catch
match Tilemap::from_tmx(path, 0) {
Ok(tm) => use_tilemap(tm),
Err(e) if e.starts_with("Failed to read file") => {
eprintln!("{} is not valid UTF-8; re-export from Tiled with UTF-8 encoding", path);
}
Err(e) => eprintln!("TMX load failed: {}", e),
} Prevention
- Configure Tiled/editor to save maps as UTF-8.
- Never rename non-XML/binary files to .tmx.
- Verify file integrity (checksums) after download/copy from network storage.
- Keep map assets in source control to detect corruption early.
When it happens
Trigger: Calling `parse_tmx(path, layer_index)` on a file that is not valid UTF-8 (e.g. saved as UTF-16 or Latin-1), a corrupted/truncated file, or a transient read error on a network/external drive.
Common situations: TMX exported from a tool with a non-UTF-8 encoding; file edited/saved by another program with a different encoding; binary file mistakenly given a .tmx extension; reading from an unstable network mount.
Related errors
- Failed to open file '{path}'
- Failed to parse file '{path}'
- Invalid tile size in file '{path}'
- Unsupported encoding in file '{path}'
- pyxel.flip is not supported on Pyxel Web
AI-assisted analysis of kitao/pyxel@50f9bd7778 (2026-09-03).
Data as JSON: /api/errors/30a54e61cd41ca93.
Report an issue: GitHub.