{"record":{"id":"acdcf723dcd2a469","repo":"kitao/pyxel","slug":"failed-to-parse-file-path","errorCode":null,"errorMessage":"Failed to parse file '{path}'","messagePattern":"Failed to parse file '(.+?)'","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pyxel-core/src/tmx_parser.rs","lineNumber":59,"sourceCode":"    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\n    let layer = tmx\n        .layers\n        .get(layer_index as usize)\n        .ok_or_else(|| format!(\"Layer {layer_index} not found in file '{path}'\"))?;\n    if layer.data.encoding != \"csv\" {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/kitao/pyxel/blob/50f9bd77780c993aca62b5b221766bde5791081d/crates/pyxel-core/src/tmx_parser.rs#L41-L77","documentation":"`parse_tmx` read the file but `serde_xml_rs::from_str::<TmxMap>` failed to deserialize it, returning this error. The XML parse or the structure did not match the expected Tiled TMX schema. The serde error detail is discarded, only the path is reported.","triggerScenarios":"Calling `parse_tmx(path, layer_index)` on a file that is not valid XML, is an uncompressed/unsupported TMX variant, uses Tiled features not modeled by TmxMap, or is a .tmx exported with a mismatched schema (missing required attributes/elements).","commonSituations":"Passing a non-XML file (JSON map, image) renamed to .tmx; a corrupted or truncated download; very new Tiled format fields the parser doesn't expect; hand-edited XML with a typo.","solutions":["Validate the file is well-formed XML (open it in Tiled or an XML validator).","Confirm the file is a Tiled TMX map, not another format renamed .tmx.","Re-export the map from Tiled using default/plain settings (no exotic extensions).","Open the file and check for hand-editing mistakes or truncation; restore from source control."],"exampleFix":"// before\nlet tilemap = Tilemap::from_tmx(\"map.json.tmx\", 0)?; // actually JSON\n// after: export from Tiled as .tmx (XML), then\nlet tilemap = Tilemap::from_tmx(\"map.tmx\", 0)?;","handlingStrategy":"validation","validationCode":"// Sanity-check the file looks like TMX XML before parse_tmx\nfn looks_like_tmx(path: &str) -> Result<(), String> {\n    let text = std::fs::read_to_string(path).map_err(|e| e.to_string())?;\n    if !text.trim_start().starts_with(\"<?xml\") && !text.contains(\"<map\") {\n        return Err(format!(\"{} does not look like a Tiled TMX (XML) file\", path));\n    }\n    Ok(())\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 parse file\") => {\n        eprintln!(\"{} is not valid TMX XML; reopen in Tiled and re-save\", path);\n    }\n    Err(e) => eprintln!(\"TMX load failed: {}\", e),\n}","preventionTips":["Open every map in Tiled at least once before shipping to confirm it parses.","Do not hand-edit TMX XML without validating afterwards.","Export maps from Tiled with default settings; avoid experimental format options.","Store maps in source control so a corrupted file can be restored."],"tags":["rust","xml","serialization","tmx","serde"],"backgroundTag":"xml-parse-error","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"}