{"record":{"id":"337ddc59c782971a","repo":"kitao/pyxel","slug":"no-tileset-found-in-file-path","errorCode":null,"errorMessage":"No tileset found in file '{path}'","messagePattern":"No tileset found in file '(.+?)'","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pyxel-core/src/tmx_parser.rs","lineNumber":68,"sourceCode":"pub 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\" {\n        return Err(err(\"Unsupported encoding in file\"));\n    }\n\n    let tile_ids: Vec<u32> = remove_whitespace(&layer.data.tiles)\n        .split(',')\n        .map(|s| s.parse::<u32>().map_err(|_| err(\"Failed to parse file\")))\n        .collect::<Result<_, _>>()?;\n\n    // Convert TMX global tile IDs into Pyxel image tile coordinates.","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/kitao/pyxel/blob/50f9bd77780c993aca62b5b221766bde5791081d/crates/pyxel-core/src/tmx_parser.rs#L50-L86","documentation":"parse_tmx found a `<map>` element with no `<tileset>` child at all. The parser requires at least one tileset because it needs `firstgid` and `columns` to convert TMX global tile IDs into Pyxel tilemap coordinates. This happens when the TMX stores tilesets in separate .tsx files (external tilesets are still emitted as `<tileset>` elements, but malformed maps or hand-written XML may omit them).","triggerScenarios":"Calling parse_tmx(path, layer_index) (directly or via from_tmx) on a TMX file whose `<map>` element contains zero `<tileset>` entries — tmx.tilesets.first() returns None.","commonSituations":"Hand-authored or programmatically generated TMX without a tileset element; a map that only references tilesets through objects/image layers stripped out by the deserializer; exporting from a tool with 'embed tilesets' disabled combined with post-processing that removed the tileset tags.","solutions":["Open the TMX file and confirm the <map> contains at least one <tileset firstgid=...> element","Re-export the map from Tiled with the tileset embedded in the .tmx file","If the tileset is external (.tsx), inline it or pre-process the XML to insert the tileset element before calling parse_tmx","Validate the TMX against the Tiled DTD/schema to catch missing required elements"],"exampleFix":"// before: map with no tileset\n<map version=\"1.10\" tilewidth=\"16\" tileheight=\"16\">\n  <layer .../>\n</map>\n// after: embed the tileset\n<map version=\"1.10\" tilewidth=\"16\" tileheight=\"16\">\n  <tileset firstgid=\"1\" name=\"tiles\" tilewidth=\"16\" tileheight=\"16\" columns=\"8\"/>\n  <layer .../>\n</map>","handlingStrategy":"validation","validationCode":"fn has_tileset(tmx_path: &str) -> std::io::Result<bool> {\n    let xml = std::fs::read_to_string(tmx_path)?;\n    Ok(xml.contains(\"<tileset\"))\n}\n\nif !has_tileset(path)? {\n    eprintln!(\"{path}: embed a <tileset> in the TMX before parsing\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Export maps from Tiled with tilesets embedded in the .tmx","Add a CI check that every .tmx contains a <tileset> element","Never hand-strip tileset elements from exported maps"],"tags":["tmx","parser","missing-tileset","resource"],"backgroundTag":"missing-required-element","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"}