# benchy-mesh: the mesh validation engine

> The engine that reads a 3D file inside fixed limits and returns one report of what it checked and found.

Canonical: https://benchy.world/docs/open-source/benchy-mesh
Last updated: 2026-10-25

## What it checks [#what-it-checks]

benchy-mesh is the engine behind every file check Benchy runs. It identifies a 3D file from its contents rather than its name, parses STL, OBJ, GLB/glTF and 3MF inside fixed limits, measures geometry and topology, and produces one report: the checks that ran, how fully each covered the file, the issues raised, and a print-readiness assessment built only from checks the file passed.

The same engine and report are used wherever Benchy checks a file. What the report says depends on the policy, the context of the check, and the resource limits it was given.

## Parser limits [#parser-limits]

Uploaded bytes are untrusted: an extension or declared media type is only a hint, and parsing runs inside explicit limits on bytes, counts, allocations, strings, textures, archive entries and expansion. That catches:

- **Truncation and lying headers** — a binary STL whose triangle count doesn't match its body, a GLB whose chunk lengths overrun the file, a header with no body.
- **Poisoned geometry** — NaN and infinite vertices in STL and OBJ are reported without contaminating the bounds or other measurements.
- **Archive attacks in 3MF** — compression-ratio and expansion limits stop zip bombs, invalid internal paths are rejected, entry counts are capped, and the model part must be the one the archive's relationships point at.
- **Resource exhaustion** — every unit of work is bounded by the execution profile in force.

Each failure carries a stable issue code, such as `BINARY_STL_LENGTH_MISMATCH`, `INVALID_ARCHIVE_PATH` or `ARCHIVE_COMPRESSION_RATIO_LIMIT_EXCEEDED`.

## The JSON contract [#the-json-contract]

A result (`MeshValidationResult`, abridged below) is camelCase, at `schemaVersion: 2`. The schema version fixes what the fields mean; the policy version changes whenever a check, threshold, issue, coverage rule, parser decision or verdict could differ for the same bytes. Branch on codes and enums, never on the English summaries.

json

```
{
  "schemaVersion": 2,
  "policyVersion": "2026.10.03.1",
  "validationProfile": "marketplace_publish",
  "executionMode": "server_enforced",
  "identification": {
    "detectedFormat": "stl",
    "confidence": "high",
    "evidence": ["content_format_signal", "bounded_parser_completed"]
  },
  "decision": { "verdict": "allow", "reasonCodes": [] },
  "checks": [
    { "id": "format.structure", "status": "passed", "coverage": "full", "summary": "…" }
  ],
  "issues": [],
  "printReadiness": {
    "assessment": "ready",
    "checks": [ … ],
    "notes": [],
    "limitations": []
  },
  "ok": true,
  "format": "stl",
  "sha256": "…"
}
```

The policy version above is an example; read the one in each report.
