# How to Debug CAD Generation Failures and Repair Geometry in Text-to-CAD

> Debug CAD generation failures and repair geometry in Text-to-CAD. Trace the pipeline, check STEP files, and regenerate GLB topology artifacts to fix geometry errors.

- Repository: [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
- Tags: how-to-guide
- Published: 2026-07-29

---

**To debug CAD generation failures in the Text-to-CAD repository, trace the pipeline through `cadpy.generation` and `cadpy.step_artifacts`, check for missing STEP files or Git LFS pointers, and regenerate GLB topology artifacts with `ensure_step_topology_artifact(..., force=True)` to surface underlying geometry errors.**

The `earthtojake/text-to-cad` repository transforms Python scripts into manufacturing-ready CAD data, including STEP files, GLB topology, and STL exports. When builds fail or geometry becomes corrupted, knowing how to debug CAD generation failures and repair geometry using the pipeline implemented in `cadpy.generation` and `cadpy.step_artifacts` allows you to diagnose root causes and apply precise fixes.

## Understanding the CAD Generation Pipeline

The generation flow consists of six distinct stages, each with specific validation checkpoints defined in the source code.

### CAD Source Discovery with `list_entry_specs()`

In [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py), the `list_entry_specs()` function walks the `models/` directory and creates an `EntrySpec` for every CAD source. This stage validates that part and assembly outputs do not clash across STL, 3MF, and native GLB formats.

### Target Resolution with `selected_entry_specs()`

The `selected_entry_specs()` function resolves user-provided references—whether source refs, CAD refs, or file paths—into concrete `EntrySpec` objects. If a reference cannot be found, it raises a `FileNotFoundError` immediately.

### Generator Execution via `run_script_generator()`

The `run_script_generator()` function (which calls `_run_script_generator_inner()`) loads Python modules containing `gen_step()` or `gen_dxf()` functions, executes them, and normalizes the payload. It verifies the generator function exists, checks the payload shape, and confirms required output paths are configured.

### STEP and DXF Serialization

The payload-writing functions `_write_shape_step_payload()`, `_write_assembly_step_payload()`, and `_write_dxf_payload()` serialize **build123d** shapes or assembly specifications to STEP files or DXF documents. If a STEP file is not actually written to disk, these functions raise a `RuntimeError`.

### Topology Artifact Validation

In [`packages/cadpy/src/cadpy/step_artifacts.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_artifacts.py), `ensure_step_topology_artifact()` guarantees a matching GLB topology file exists for every STEP file. If the artifact is missing or stale, it attempts regeneration; on failure, it raises `StepTopologyArtifactError` with code `glb_regeneration_failed`.

### Selector Manifest Reporting

Finally, `_report_selector_manifest_change()` in [`generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/generation.py) compares previous and current selector manifests, emitting warnings when geometry or topology changes. This alerts you when cached selector data must be refreshed.

## Common Failure Points and Diagnostic Fixes

When you debug CAD generation failures, specific symptoms point to distinct root causes in the pipeline.

- **`RuntimeError: … did not write …`** — This indicates the generator did not create the expected STEP file, often because `gen_step()` returned a shape but the `EntrySpec` lacks a valid `step_path`. Ensure your generator returns a proper envelope (`shape`, `instances`, or `children`) and that the `step_path` attribute is not `None`.

- **`StepTopologyArtifactError` with code `glb_regeneration_failed`** — The GLB topology could not be regenerated, usually due to a broken STEP file, missing LFS object, or unhandled generator exception. Check the original STEP file in the CAD Viewer. If the file is a Git LFS pointer, run `git lfs pull`. Otherwise, inspect the generator for unhandled exceptions and fix the underlying shape definition.

- **Collision errors** (`STL output collision`, `3MF output collision`, `Native GLB output collision`) — Two different sources map to the same output file path. The validation occurs in `_validate_part_render_output_paths()` in [`generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/generation.py). Rename conflicting outputs or adjust the `output=` CLI pair to assign unique paths.

- **Selector manifest mismatch** (`selector topology changed` / `selector geometry changed`) — The underlying STEP topology or geometry changed after selectors were cached. This is reported by `_report_selector_manifest_change()`. Re-run any code consuming selectors (e.g., `cadpy.selector`) to reload the new manifest.

- **Git LFS pointer detected** — A STEP file is stored as an LFS pointer rather than actual file data. Detected by `_is_git_lfs_pointer()` in [`generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/generation.py). Run `git lfs fetch` or `git lfs pull` to resolve the file contents.

## Interactive Debugging Workflow

Use this Python script to manually trace through the pipeline and surface hidden errors:

```python
from cadpy.generation import list_entry_specs, selected_entry_specs, run_script_generator
from cadpy.step_artifacts import ensure_step_topology_artifact
from cadpy.cli_logging import CliLogger
from pathlib import Path

# 1. List all CAD sources discovered in the repository

all_specs = list_entry_specs()
print("All CAD sources:", [s.source_ref for s in all_specs])

# 2. Resolve your target reference to a concrete EntrySpec

target_ref = "parts/example_part"  # Replace with your source ref

specs = selected_entry_specs(all_specs, [target_ref])
spec = specs[0]

# 3. Execute the generator manually to catch exceptions

scene = run_script_generator(spec, "gen_step", logger=CliLogger("debug"))

# 4. Verify the STEP file exists and is not an LFS pointer

assert spec.step_path is not None, "STEP path not configured"
assert spec.step_path.is_file(), f"STEP file missing at {spec.step_path}"

# 5. Force GLB regeneration to expose topology errors

artifact = ensure_step_topology_artifact(
    target=spec,
    force=True,  # Forces regeneration to show full stack trace

    logger=CliLogger("debug")
)
print("GLB artifact ready at:", artifact.glb_path)

```

This workflow prints the catalog of sources, resolves the target, executes the generator, validates the STEP file is real (not a pointer), and forces GLB regeneration to reveal errors that would otherwise be wrapped in a `StepTopologyArtifactError`.

## Repairing Geometry Issues

When generators raise `TypeError` or `RuntimeError` due to malformed geometry, apply these specific fixes:

- **Zero-length axis** (`zero_axis` error) — Ensure any `Vector` used for an axis definition is non-zero in your shape definition.

- **Invalid mass or inertia** (`invalid_mass`, `invalid_inertia_matrix`) — Provide realistic mass values or allow automatic computation; avoid negative masses.

- **Missing mesh files** (`missing_mesh_file`) — Verify external meshes (STL, OBJ) referenced by the generator exist at the specified paths and are correctly added to the repository (use LFS if large).

- **Unsupported STEP topology** (`unsupported_step_topology`) — Regenerate the STEP using the latest `build123d` version; older exporters may produce topology that `cadpy` cannot parse.

- **Stale GLB topology** (`glb_regeneration_failed`) — Run regeneration with `ensure_step_topology_artifact(..., force=True)` after fixing the STEP. If the STEP is corrupted, rebuild it from the source script.

## Key Source Files for Debugging

| File | Role |
|------|------|
| [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) | Core pipeline: discovers specs, runs generators, writes STEP/DXF, validates outputs, and checks for Git LFS pointers. |
| [`packages/cadpy/src/cadpy/step_artifacts.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_artifacts.py) | GLB topology artifact creation, validation, and regeneration logic. |
| [`packages/cadpy/src/cadpy/step_scene.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_scene.py) | Loads STEP files into `LoadedStepScene` and provides mesh resolution utilities. |
| [`packages/cadpy/src/cadpy/glb.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/glb.py) | Exports GLB topology from STEP scenes and builds selector manifests. |
| [`packages/cadpy/src/cadpy/metadata.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/metadata.py) | Defines default mesh tolerances and embeds generator metadata. |

These files illustrate the complete CAD generation lifecycle, from source discovery through error detection and recovery.

## Summary

- The generation pipeline flows from **source discovery** (`list_entry_specs`) through **generator execution** (`run_script_generator`) to **topology validation** (`ensure_step_topology_artifact`).
- **RuntimeError** on missing STEP files usually indicates generator logic errors or misconfigured `step_path` values.
- **StepTopologyArtifactError** with code `glb_regeneration_failed` signals broken STEP files, missing LFS objects, or generator exceptions requiring manual inspection.
- Use the interactive debugging script to manually execute generators and force GLB regeneration with `force=True` to expose hidden stack traces.
- Repair geometry by fixing zero-length vectors, validating mass properties, ensuring mesh files exist, and updating to latest `build123d` exporters.

## Frequently Asked Questions

### What causes a `StepTopologyArtifactError` with code `glb_regeneration_failed`?

This error occurs in [`packages/cadpy/src/cadpy/step_artifacts.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_artifacts.py) when `ensure_step_topology_artifact()` cannot regenerate the GLB topology file from a STEP source. Common causes include corrupted STEP data, unhandled exceptions in the generator script, or the STEP file being a Git LFS pointer rather than actual geometry data. Check the STEP file in a CAD viewer and run `git lfs pull` if necessary.

### How do I fix Git LFS pointer errors in STEP files?

When `_is_git_lfs_pointer()` in [`generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/generation.py) detects a pointer file instead of STEP data, the file content resembles a text pointer rather than binary CAD data. Run `git lfs fetch` followed by `git lfs pull` to download the actual file contents. In deployment environments, ensure Git LFS is installed and configured before running the generation pipeline.

### Why am I seeing output collision errors for STL or 3MF files?

The validator `_validate_part_render_output_paths()` raises collision errors when two different `EntrySpec` objects define the same output path for STL, 3MF, or native GLB files. This prevents one generator from overwriting another's output. Resolve by renaming one of the conflicting output files or adjusting the `output=` CLI argument to provide unique paths for each target.

### How do I resolve selector manifest mismatches after updating geometry?

The `_report_selector_manifest_change()` function emits warnings when cached selector manifests no longer match the current STEP topology or geometry. This happens when you modify a generator and rebuild the CAD without updating dependent selector code. Re-run any modules consuming selectors (such as `cadpy.selector`) to reload the updated manifest and clear stale cache entries.