{"record":{"id":"5e5c91075346e981","repo":"kitao/pyxel","slug":"failed-to-open-file-path","errorCode":null,"errorMessage":"Failed to open file '{path}'","messagePattern":"Failed to open file '(.+?)'","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pyxel-core/src/tmx_parser.rs","lineNumber":54,"sourceCode":"\n#[derive(Debug, Deserialize)]\n#[serde(rename = \"map\")]\nstruct TmxMap {\n    #[serde(rename = \"@tilewidth\")]\n    tilewidth: u32,\n    #[serde(rename = \"@tileheight\")]\n    tileheight: u32,\n    #[serde(rename = \"tileset\", default)]\n    tilesets: Vec<Tileset>,\n    #[serde(rename = \"layer\", default)]\n    layers: Vec<Layer>,\n}\n\npub fn parse_tmx(path: &str, layer_index: u32) -> Result<RcTilemap, String> {\n    let err = |msg| format!(\"{msg} '{path}'\");\n\n    // Load and validate the TMX layer.\n    let mut file = File::open(path).map_err(|_| err(\"Failed to open file\"))?;\n    let mut tmx_text = String::new();\n    file.read_to_string(&mut tmx_text)\n        .map_err(|_| err(\"Failed to read file\"))?;\n\n    let tmx: TmxMap = serde_xml_rs::from_str(&tmx_text).map_err(|_| err(\"Failed to parse file\"))?;\n\n    if tmx.tilewidth != TILE_SIZE || tmx.tileheight != TILE_SIZE {\n        return Err(err(\"Invalid tile size in file\"));\n    }\n\n    let tileset = tmx\n        .tilesets\n        .first()\n        .ok_or_else(|| err(\"No tileset found in file\"))?;\n    let columns = tileset\n        .columns\n        .ok_or_else(|| err(\"No embedded tileset in file\"))?;\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/kitao/pyxel/blob/50f9bd77780c993aca62b5b221766bde5791081d/crates/pyxel-core/src/tmx_parser.rs#L36-L72","documentation":"`parse_tmx` failed to open the TMX file at the given path and returns this formatted error string via `Result::Err`. The underlying io::Error is discarded, so only the path is reported. It is the first validation step of loading a Tiled tilemap.","triggerScenarios":"Calling `parse_tmx(path, layer_index)` (or `Tilemap::from_tmx`) where `File::open(path)` fails: the file does not exist, the path is wrong, permission is denied, or the path is a directory.","commonSituations":"Typo in the .tmx filename; passing a path relative to the wrong working directory (e.g. binary run from a different cwd); missing data files in a packaged/deployed build; reading a file the user lacks permissions for.","solutions":["Verify the file exists at the exact path (check spelling and extension).","Use an absolute path or resolve the path relative to the executable/resources, not the process cwd.","Check file permissions for the running user.","Confirm the asset is included in packaged builds (e.g. embedded resources or copied data dir)."],"exampleFix":"// before\nlet tilemap = Tilemap::from_tmx(\"assets/level.tmx\", 0)?;\n// after\nlet path = std::path::Path::new(env!(\"CARGO_MANIFEST_DIR\")).join(\"assets/level.tmx\");\nassert!(path.exists(), \"missing TMX: {}\", path.display());\nlet tilemap = Tilemap::from_tmx(path.to_str().unwrap(), 0)?;","handlingStrategy":"validation","validationCode":"// Check file presence/permissions before calling parse_tmx\nfn tmx_readable(path: &str) -> Result<(), String> {\n    let p = std::path::Path::new(path);\n    if !p.is_file() {\n        return Err(format!(\"TMX file missing: {}\", path));\n    }\n    std::fs::File::open(p).map(|_| ()).map_err(|e| format!(\"cannot open {}: {}\", path, e))\n}","typeGuard":null,"tryCatchPattern":"match Tilemap::from_tmx(path, 0) {\n    Ok(tm) => use_tilemap(tm),\n    Err(e) if e.starts_with(\"Failed to open file\") => {\n        eprintln!(\"TMX path bad ({}): check cwd and packaged assets\", e);\n    }\n    Err(e) => eprintln!(\"TMX load failed: {}\", e),\n}","preventionTips":["Resolve asset paths relative to the executable or embed them at build time, never rely on cwd.","Ship a startup check that verifies all required .tmx assets exist before the game loop.","Include data files in packaging/deploy configuration.","Log the absolute path (canonicalize) when loading fails."],"tags":["rust","io","file-not-found","tmx","path"],"backgroundTag":"file-not-found","analyzedSha":"50f9bd77780c993aca62b5b221766bde5791081d","analyzedAt":"2026-09-03T10:27:43.285Z","contentChangedAt":"2026-09-03T10:27:43.285Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}