diff --git a/crates/svg/src/import/text.rs b/crates/svg/src/import/text.rs
index 32dbde6c..8ddd0f05 100644
--- a/crates/svg/src/import/text.rs
+++ b/crates/svg/src/import/text.rs
@@ -594,6 +594,11 @@ impl Ctx {
obj.xf = parse_transform(r.attribute("transform")) * origin;
let servers = vec![(None, None); obj.runs.len()];
let b = obj.xf.transform_rect_bbox(frame);
+ // A size, place or transform past what numbers hold (`width="1e999"`) has no frame to set type in.
+ if ![b.x0, b.y0, b.x1, b.y1].iter().all(|v| v.is_finite()) {
+ warnings.push(format!("{label}: flowed text (flowRoot) with a region too large to place was left out"));
+ return None;
+ }
let marker = Rect::new(b.x0, b.y0, b.x1.max(b.x0 + 1.0), b.y1.max(b.y0 + 1.0));
let name = t.attribute("id").unwrap_or("").to_string();
Some((PendingText { name, obj, servers, paints: 0, non_scaling: false, under: None, marker }, Vec::new()))
diff --git a/crates/svg/tests/import_text.rs b/crates/svg/tests/import_text.rs
index 3d587a56..4d862b58 100644
--- a/crates/svg/tests/import_text.rs
+++ b/crates/svg/tests/import_text.rs
@@ -612,3 +612,20 @@ fn flowed_text_becomes_area_type() {
assert!(close(t.runs[0].style.size * t.xf.determinant().abs().sqrt(), 16.0, 1e-6));
assert!(w.iter().any(|w| w.contains("flowRoot")), "{w:?}");
}
+
+/// Flowed text that can't be read is left out with a warning each, and never stops the import: no
+/// region, a region too large for numbers, a flowRoot inside a flowRoot (read once, as the outer one).
+#[test]
+fn flowed_text_that_cannot_be_read_is_reported() {
+ let (d, w) = import_with_report(&svg(
+ r#"No region
+ Huge
+ Far
+ Outerinner"#,
+ ))
+ .unwrap();
+ assert_eq!(only_text(&d).plain_text(), "Outer\ninner");
+ for id in ["none", "huge", "far"] {
+ assert!(w.iter().any(|w| w.contains(id) && w.contains("flowRoot")), "{id}: {w:?}");
+ }
+}