nexu-io/open-design · error · OverflowError

cursor at {self.y} exceeds footer rail {self.cap}; reduce bl

Error message

cursor at {self.y} exceeds footer rail {self.cap}; reduce block height or split slide

What it means

Raised by the Cursor.take() helper documented in skills/pptx-html-fidelity-audit/SKILL.md when advancing the content cursor would push self.y past self.cap (CONTENT_MAX_Y, the footer rail). It is an intentional OverflowError that turns a silent visual overflow (content crossing the footer) into a loud build error during pptx re-export.

Source

Thrown at skills/pptx-html-fidelity-audit/SKILL.md:136

FOOTER_TOP     = Inches(6.85)     # footer row pinned here, edge-to-edge
```

> **Customizing the rails.** The defaults above suit a 16:9 canvas with a slim footer. If your design system uses a wider footer or a 4:3 canvas, override these constants in your export script and pass the same values to `verify_layout.py` via `--content-max-y` / `--canvas-h` / `--canvas-w`. See `references/layout-discipline.md` §1 for the full constant table.


**Use a cursor for content blocks instead of pinning each block at an absolute y:**

```python
class Cursor:
    """Advances down the slide; refuses to cross the footer rail."""
    def __init__(self, y_start, cap=CONTENT_MAX_Y):
        self.y = y_start
        self.cap = cap
    def take(self, h, gap=Inches(0.12)):  # ~1 line of whitespace at 14pt; tighten/loosen per design system
        top = self.y
        self.y = top + h + gap
        if self.y > self.cap:
            raise OverflowError(
                f"cursor at {self.y} exceeds footer rail {self.cap}; "
                f"reduce block height or split slide"
            )
        return top
```

For each slide, instantiate `Cursor(MARGIN_TOP)` and `take(height)` each block in reading order. The slide refuses to render if any block would cross the rail, so overflows become loud build errors instead of silent visual bugs.

**Hero (vertically-centered) slides use a budget instead of a cursor:**

```python
def hero_layout(blocks):
    """blocks = list of (height, gap_after) tuples in reading order."""
    total = sum(h + g for h, g in blocks)
    y_start = (CANVAS_H - total) / 2
    return Cursor(y_start)
```

View on GitHub (pinned to 5be4028344)

Solutions

  1. Reduce the offending block's height (tighten image height, trim text, shrink padding).
  2. Split the slide into two slides so each fits within the rail.
  3. Raise CONTENT_MAX_Y only if the design system genuinely allows a smaller footer (update FOOTER_TOP accordingly and pass --content-max-y to verify_layout.py).
  4. Switch the slide to hero_layout (centered budget) if it is a vertically-centered hero, not a top-pinned flow.

Example fix

# before
cursor = Cursor(MARGIN_TOP)
cursor.take(Inches(6.5))   # single block too tall, raises OverflowError
# after
cursor.take(Inches(3.0))
cursor.take(Inches(2.8))   # split into two blocks that fit
Defensive patterns

Strategy: try-catch

Validate before calling

if cursor.y + h + gap > cursor.cap:
    raise SystemExit(f"block of height {h} would overflow footer rail; split or shrink")

Try / catch

try:
    top = cursor.take(block_height)
except OverflowError as e:
    # split the slide or shrink the block, then retry
    split_or_shrink(block, e)
    raise

Prevention

When it happens

Trigger: Calling cursor.take(h) for a block whose height plus gap pushes the running y beyond CONTENT_MAX_Y; too many blocks stacked in reading order; a single oversized block (e.g. a tall image or long bullet list).

Common situations: Re-exporting a deck where a slide has more content than the content area allows; design system changed footer height so CONTENT_MAX_Y shrank; image heights computed too generously.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/65052b9ce971e9aa. Report an issue: GitHub.