# Troubleshooting Build123d Modeling Errors in Text-to-CAD: 5 Common Issues and Fixes

> Fix common build123d modeling errors in text-to-CAD. Learn to resolve selector syntax issues, missing files, empty meshes, export failures, and viewer mismatches. Improve your CAD generation workflow now.

- Repository: [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
- Tags: troubleshooting-guide
- Published: 2026-08-04

---

**Most Build123d modeling errors in the text-to-CAD pipeline stem from invalid selector syntax, missing STEP files, empty mesh objects, export failures, or viewer asset mismatches — all traceable to specific source files in `packages/cadpy` and the `viewer` package.**

The [text-to-cad](https://github.com/earthtojake/text-to-cad) repository by earthtojake converts natural language prompts into 3D CAD artifacts (STEP, STL, 3MF, GLB) using a Build123d-based Python engine. When troubleshooting Build123d modeling errors, understanding the three core pipeline components — the **CAD Python engine** (`packages/cadpy`), the **3MF/GLB exporters**, and the **CAD viewer** — lets you pinpoint failures fast.

## Invalid Selector or Axis Errors

The most frequent input validation failure occurs when selector strings contain unsupported axes.

**Error message:** `"Axis must be one of x, y, z"` — raised in [`packages/cadpy/src/cadpy/validators.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/validators.py).

**Root cause:** A selector like `select("body.u")` or `select("link.foo")` passes an invalid axis value. The validator strictly enforces `x`, `y`, or `z` only.

**Resolution:** Audit selector construction against the grammar documented in [`skills/cad/SKILL.md`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/SKILL.md). Cross-reference dynamic axis values before building selector strings.

```python

# Wrong — raises validation error

selector = "link.u"

# Correct

selector = "link.x"

```

For programmatic selector building, add a guard:

```python
def safe_select(axis: str):
    if axis not in ("x", "y", "z"):
        raise ValueError(f"Axis must be one of x, y, z; got {axis!r}")
    return f"select_axis_{axis}"

```

## Missing or Unresolved STEP Files

STEP file resolution failures block the pipeline when referenced geometry cannot be located.

**Error message:** `"STEP file does not exist: <path>"` — raised in [`packages/cadpy/src/cadpy/step_scene.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_scene.py) at line 1140.

**Root causes:**

- Heavy assets remain as Git LFS pointers rather than actual files
- Generation pipeline hasn't produced the expected STEP output
- Dynamic references (`model://my_part`) point to nonexistent entries in `models/`

**Resolution steps:**

1. Pull large files: `git lfs pull --include="benchmarks/**"`
2. Regenerate missing assets via the workflow in [`skills/cad/SKILL.md`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/SKILL.md)
3. Verify dynamic model references exist in the filesystem

## Empty Mesh or Prototype Errors

Degenerate geometry — zero-volume shapes from failed extrusions or complete boolean subtractions — causes exporter crashes.

**Error message:** `"Cannot write empty 3MF mesh object: <name>"` — raised in [`packages/cadpy/src/cadpy/threemf.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/threemf.py) at line 251.

**Root cause:** The geometry source produced no vertices. Common triggers include:
- Zero-height extrusions
- Boolean operations that subtract all material
- Scaling operations that collapse dimensions

**Resolution:** Add dimensional guards before export:

```python
if shape.bounding_box.volume < 1e-6:
    raise ValueError("Generated shape is too small or degenerate")

```

## Runtime Export Failures

STEP export failures originate in the underlying OpenCascade (OCC) writer when preconditions aren't met.

**Error message:** `"Failed to write STEP file: <output_path>"` — raised in [`packages/cadpy/src/cadpy/step_export.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_export.py) at line 338.

**Root causes:**
- XCAF document contains no valid geometry
- Output directory doesn't exist or lacks write permissions
- Filesystem path exceeds platform limits

**Resolution checklist:**

- **Pre-validate geometry:** Confirm `scene.has_geometry` returns `True` before export
- **Ensure writable paths:** Create parent directories explicitly

```python
import pathlib

def export_step(scene, out_path: pathlib.Path):
    out_path.parent.mkdir(parents=True, exist_ok=True)
    try:
        scene.write_step(out_path)
    except RuntimeError as e:
        raise RuntimeError(f"Failed to write STEP file: {out_path}") from e

```

## CAD Viewer Asset Not Found

Viewer 404 errors indicate a naming mismatch between exporter output and viewer expectations.

**Error message:** `404 — model.glb not found` (viewer logs, no traceback).

**Root cause:** The 3MF exporter in [`threemf.py`](https://github.com/earthtojake/text-to-cad/blob/main/threemf.py) line 543 (method `_write_package`) names the internal model file `model.glb`, but the viewer expects `3D/3dmodel.model` inside the ZIP structure — or vice versa depending on fork customizations.

**Resolution:** Maintain naming consistency between `_write_package` and [`metadata.json`](https://github.com/earthtojake/text-to-cad/blob/main/metadata.json) in the viewer. If you've modified either component, verify:

| Component | Expected Path |
|-----------|-------------|
| Exporter ([`threemf.py`](https://github.com/earthtojake/text-to-cad/blob/main/threemf.py)) | `model.glb` inside ZIP |
| Viewer package structure | `3D/3dmodel.model` per 3MF spec |

## Systematic Debugging Workflow

When troubleshooting Build123d modeling errors outside these five categories, follow this diagnostic sequence:

1. **Enable verbose logging** — Most skills accept `--debug` to trace pipeline stages
2. **Inspect artifacts directly** — Open `.step` or `.zip` outputs in FreeCAD or similar tools
3. **Check LFS status** — Run `git lfs ls-files` to identify pointer-only assets
4. **Reproduce with tests** — The `tests/python` directory contains intentional failure cases for each error type

## Key Files for Debugging

| File | Purpose |
|------|---------|
| [`packages/cadpy/src/cadpy/validators.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/validators.py) | Selector and geometry input validation |
| [`packages/cadpy/src/cadpy/threemf.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/threemf.py) | 3MF/GLB export logic and mesh writing |
| [`packages/cadpy/src/cadpy/step_scene.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_scene.py) | STEP loading and XCAF document handling |
| [`packages/cadpy/src/cadpy/step_export.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_export.py) | STEP export with OCC integration |
| [`viewer/packages/cadjs/src/lib/viewer/webglSupport.js`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/packages/cadjs/src/lib/viewer/webglSupport.js) | Viewer-side asset loading diagnostics |
| [`skills/cad/SKILL.md`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/SKILL.md) | CLI workflow and command reference |

## Summary

- **Validate selectors early** — axes must be `x`, `y`, or `z` per [`validators.py`](https://github.com/earthtojake/text-to-cad/blob/main/validators.py)
- **Pull LFS assets** before running pipelines that reference benchmark models
- **Guard against degenerate geometry** with volume checks before 3MF export
- **Ensure export preconditions** — writable directories and non-empty scenes
- **Maintain naming conventions** between [`threemf.py`](https://github.com/earthtojake/text-to-cad/blob/main/threemf.py) exporters and viewer expectations

## Frequently Asked Questions

### What causes the "Axis must be one of x, y, z" error in text-to-cad?

This error originates in [`packages/cadpy/src/cadpy/validators.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/validators.py) when a selector string contains an unsupported axis value. The validator enforces strict axis constraints because downstream geometry operations depend on canonical directions. Check selector construction code for typos or dynamic axis generation that might produce values like `u`, `v`, or arbitrary strings.

### Why does my STEP export fail with "Failed to write STEP file"?

The error at `step_export.py:338` typically indicates either an unwritable output path or an empty XCAF document. Verify directory permissions with `mkdir(parents=True, exist_ok=True)` and ensure `scene.has_geometry` before calling `write_step()`. The underlying OpenCascade writer requires at least one valid solid in the document.

### How do I fix "Cannot write empty 3MF mesh object" errors?

This error at `threemf.py:251` means your Build123d operations produced a shape with zero vertices. Common causes include zero-thickness extrusions or boolean subtractions that removed all material. Add a volume check against `shape.bounding_box.volume` and raise a descriptive error before reaching the exporter, or inspect preceding geometry operations for dimensional collapse.

### Why does the CAD viewer show 404 for model.glb?

The viewer expects a specific internal structure within the 3MF ZIP package. If `_write_package` in `threemf.py:543` names the model file differently than the viewer's [`metadata.json`](https://github.com/earthtojake/text-to-cad/blob/main/metadata.json) specifies, the loading fails. Either preserve the default `model.glb` naming or synchronize both components if you've forked the exporter.