kitao/pyxel · error
No embedded tileset in file '{path}'
Error message
No embedded tileset in file '{path}' What it means
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.
Source
Thrown at crates/pyxel-core/src/tmx_parser.rs:71
// 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)
.ok_or_else(|| format!("Layer {layer_index} not found in file '{path}'"))?;
if layer.data.encoding != "csv" {
return Err(err("Unsupported encoding in file"));
}
let tile_ids: Vec<u32> = remove_whitespace(&layer.data.tiles)
.split(',')
.map(|s| s.parse::<u32>().map_err(|_| err("Failed to parse file")))
.collect::<Result<_, _>>()?;
// Convert TMX global tile IDs into Pyxel image tile coordinates.
let tilemap = Tilemap::try_new(layer.width, layer.height, ImageSource::Index(0))
.map_err(|_| err("Layer dimensions are too large in file"))?;
let mut tilemap_ref = rc_mut!(tilemap);View on GitHub (pinned to 50f9bd7778)
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
Example fix
// before <tileset firstgid="1" name="tiles" tilewidth="16" tileheight="16" tilecount="64"/> // after (128px-wide sheet / 16px tiles = 8 columns) <tileset firstgid="1" name="tiles" tilewidth="16" tileheight="16" tilecount="64" columns="8"/>
Defensive patterns
Strategy: validation
Validate before calling
fn tileset_has_columns(tmx_path: &str) -> std::io::Result<bool> {
let xml = std::fs::read_to_string(tmx_path)?;
let has_ts = xml.contains("<tileset");
let has_cols = xml.split("<tileset").skip(1)
.next().map(|s| s.contains("columns="))
.unwrap_or(false);
Ok(has_ts && has_cols)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- No tileset found in file '{path}'
- Unsupported encoding in file '{path}'
- Failed to open file '{path}'
- Failed to read file '{path}'
- Failed to parse file '{path}'
AI-assisted analysis of kitao/pyxel@50f9bd7778 (2026-09-03).
Data as JSON: /api/errors/456fa19b5615f6a8.
Report an issue: GitHub.