{"record":{"id":"456fa19b5615f6a8","repo":"kitao/pyxel","slug":"no-embedded-tileset-in-file-path","errorCode":null,"errorMessage":"No embedded tileset in file '{path}'","messagePattern":"No embedded tileset in file '(.+?)'","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pyxel-core/src/tmx_parser.rs","lineNumber":71,"sourceCode":"    // 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.\n    let tilemap = Tilemap::try_new(layer.width, layer.height, ImageSource::Index(0))\n        .map_err(|_| err(\"Layer dimensions are too large in file\"))?;\n    let mut tilemap_ref = rc_mut!(tilemap);","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/kitao/pyxel/blob/50f9bd77780c993aca62b5b221766bde5791081d/crates/pyxel-core/src/tmx_parser.rs#L53-L89","documentation":"The TMX contains a tileset, but its `columns` attribute is absent (the Tileset struct models `@columns` as Option<u32>). The parser needs the column count to compute tile (x, y) coordinates via id % columns and id / columns, so it refuses to proceed. In practice this means the tileset is not an embedded tileset with image data — e.g. it is an external or image-collection tileset without a columns attribute.","triggerScenarios":"parse_tmx encounters `<tileset firstgid=\"1\" ...>` with no `columns` attribute, which is typical of external .tsx-referenced tilesets or image-collection tilesets, where the attribute only exists on embedded image-based tilesets.","commonSituations":"Using Tiled's image collection tilesets; exporting a map that references a .tsx file instead of embedding the tileset; manually trimming attributes from the tileset element; older tooling that omits optional attributes.","solutions":["Embed the tileset in the .tmx so Tiled writes the `columns` attribute (Tileset > Embed in map)","Add columns=\"N\" to the <tileset> element, matching the tileset image width divided by tile width","If using an image-collection tileset, convert it to a single-image tileset that has a columns count","Pre-process the XML to inject the columns attribute before parsing"],"exampleFix":"// before\n<tileset firstgid=\"1\" name=\"tiles\" tilewidth=\"16\" tileheight=\"16\" tilecount=\"64\"/>\n// after (128px-wide sheet / 16px tiles = 8 columns)\n<tileset firstgid=\"1\" name=\"tiles\" tilewidth=\"16\" tileheight=\"16\" tilecount=\"64\" columns=\"8\"/>","handlingStrategy":"validation","validationCode":"fn tileset_has_columns(tmx_path: &str) -> std::io::Result<bool> {\n    let xml = std::fs::read_to_string(tmx_path)?;\n    let has_ts = xml.contains(\"<tileset\");\n    let has_cols = xml.split(\"<tileset\").skip(1)\n        .next().map(|s| s.contains(\"columns=\"))\n        .unwrap_or(false);\n    Ok(has_ts && has_cols)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use single-image tilesets (not image collections) so Tiled writes `columns`","Embed tilesets in the map rather than referencing external .tsx files","Assert columns == image_width / tile_width when authoring TMX by hand"],"tags":["tmx","parser","tileset","missing-attribute"],"backgroundTag":"missing-required-attribute","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"}