# How validateGraph Performs Schema Validation with Auto-Fix and Normalization

> Discover how Egonex-AI/Understand-Anything's validateGraph function performs schema validation. It sanitizes, normalizes aliases, auto-fixes fields, and validates with Zod, returning a full audit trail.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: deep-dive
- Published: 2026-06-28

---

**The `validateGraph` function executes a four-tier validation pipeline that sanitizes raw input, normalizes LLM-generated type aliases, auto-fixes missing fields with sensible defaults, and validates against strict Zod schemas—returning a detailed audit trail of all corrections.**

The `validateGraph` function serves as the central gatekeeper for knowledge-graph integrity in the **Understand-Anything** repository. Located in [`understand-anything-plugin/packages/core/src/schema.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/schema.ts), this function ensures that any graph object persisted or served to the dashboard meets strict structural requirements while automatically repairing common data inconsistencies.

## The Three-Stage Preparation Pipeline

Before strict schema validation occurs, `validateGraph` processes raw input through three distinct preparatory stages that handle data cleaning and repair.

### Sanitization: Removing Unsafe Values

The **sanitization** stage invokes `sanitizeGraph` (lines 48-94 in [`schema.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/schema.ts)) to eliminate unsafe values that could corrupt downstream processing. This function removes `null` collections and normalizes enumerations to lowercase strings, ensuring that the graph structure is internally consistent before validation proceeds.

### Normalization: Resolving LLM Aliases

The **normalization** stage calls `normalizeGraph` (lines 96-101) to rewrite LLM-generated aliases into canonical node and edge types defined in the schema. For example, the shorthand `"fn"` is mapped to `"function"`, and complexity indicators like `"high"` are normalized to `"complex"`. This translation layer ensures that machine-generated graphs align with the repository's strict typing conventions.

### Auto-Fixing: Coercion and Default Injection

The **auto-fixing** stage employs `autoFixGraph` (lines 99-150) to supply sensible defaults for missing fields and coerce incompatible types. This function converts string weights (e.g., `"0.7"`) to numeric values (`0.7`), replaces `null` tour arrays with empty arrays, and records every modification as a `GraphIssue` entry for audit purposes.

## The Four-Tier Validation Architecture

After preparation, `validateGraph` executes a comprehensive four-tier validation strategy that progressively enforces constraints:

**Tier 1: Sanitization**
- Already completed via `sanitizeGraph`
- Removes null references and normalizes enums

**Tier 2: Auto-Fix Application**
- Executes `autoFixGraph` to handle defaults and type coercion
- Populates the `issues` array with correction records

**Tier 3: Strict Schema Validation**
- Validates individual nodes, edges, layers, and tour steps against Zod schemas (`GraphNodeSchema.safeParse`, `GraphEdgeSchema.safeParse`)
- **Drops invalid items** rather than failing entirely
- Records dropped items as `GraphIssue` entries with level `"dropped"`

**Tier 4: Fatal Integrity Checks**
- Aborts validation immediately for non-object inputs, malformed top-level collections, missing project metadata, or zero valid nodes
- Returns `success: false` with a `fatal` error message

## Understanding the ValidationResult Interface

The function returns a structured `ValidationResult` interface that provides complete transparency into the validation process:

```typescript
export interface ValidationResult {
  success: boolean;
  data?: KnowledgeGraph;          // only when success===true
  issues: GraphIssue[];           // all warnings, auto-fixes and drops
  fatal?: string;                // present when success===false
  errors?: string[];              // deprecated, kept for backward compatibility
}

```

The **issues** array captures every auto-corrected field, every dropped element, and any fatal problem, giving callers a full audit trail of what was changed or why validation failed.

## Practical Implementation Example

The following example demonstrates how `validateGraph` handles a raw graph containing aliases, string weights, and null values:

```typescript
import { validateGraph } from "@understand-anything/core";

// A raw graph that may contain missing fields, aliases, or bad types
const rawGraph = {
  version: "1.0.0",
  project: { name: "demo", languages: ["ts"], frameworks: [], description: "", analyzedAt: "", gitCommitHash: "" },
  nodes: [{ id: "n1", type: "fn", name: "doStuff", summary: "…", tags: [], complexity: "high" }],
  edges: [{ source: "n1", target: "n2", type: "invokes", direction: "outbound", weight: "0.7" }],
  layers: [],
  tour: null,
};

const result = validateGraph(rawGraph);

if (result.success) {
  console.log("Validated graph:", result.data);
} else {
  console.error("Graph validation failed:", result.fatal);
  console.log("All issues:", result.issues);
}

```

This execution performs the following transformations automatically:
- Converts `"fn"` → `"function"` (alias normalization)
- Maps `"high"` → `"complex"` (complexity alias)
- Coerces the weight string `"0.7"` → `0.7` (type coercion)
- Replaces the `null` `tour` with an empty array (sanitization)

## Key Source Files and Implementation Details

The validation logic is distributed across three critical files in the Egonex-AI/Understand-Anything repository:

- **[`understand-anything-plugin/packages/core/src/schema.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/schema.ts)** — Defines the Zod schemas (`GraphNodeSchema`, `GraphEdgeSchema`, `ProjectMetaSchema`), alias maps, and the complete `validateGraph` implementation (lines 48-150+)
- **[`understand-anything-plugin/packages/core/src/persistence/index.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/persistence/index.ts)** — Demonstrates how `validateGraph` is invoked when loading persisted graphs, throwing on fatal errors
- **[`understand-anything-plugin/packages/core/src/__tests__/schema.test.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/__tests__/schema.test.ts)** — Contains unit tests exercising validation edge cases, auto-fix scenarios, and normalization behavior

## Summary

- **Three-stage preparation**: `sanitizeGraph` cleans unsafe values, `normalizeGraph` resolves LLM aliases, and `autoFixGraph` applies defaults and type coercion
- **Four-tier validation**: Progressive enforcement from basic cleaning through fatal integrity checks that abort on catastrophic failures
- **Audit transparency**: Every auto-fix, dropped item, and validation error is recorded in the `issues` array of the `ValidationResult`
- **Zod-based schemas**: Strict validation using `safeParse` methods that filter invalid nodes and edges rather than failing the entire graph
- **Repository location**: Core implementation resides in [`understand-anything-plugin/packages/core/src/schema.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/schema.ts) within the Egonex-AI/Understand-Anything codebase

## Frequently Asked Questions

### What happens when validateGraph encounters an invalid node or edge?

Rather than failing the entire validation, the function drops individual invalid items and continues processing. Each dropped element is recorded in the `issues` array with a `"dropped"` level designation, allowing the graph to load while logging exactly which elements were removed and why.

### How does validateGraph handle LLM-generated type aliases like "fn"?

The function passes input through `normalizeGraph`, which contains alias mappings that translate shorthand or variant type names to canonical schema values. For example, `"fn"` becomes `"function"` and `"high"` complexity becomes `"complex"` before structured validation occurs.

### What is the difference between a fatal error and a dropped item in validateGraph?

Fatal errors occur at Tier 4 validation and immediately abort processing, returning `success: false` with a `fatal` message—these include non-object inputs, missing project metadata, or zero valid nodes. Dropped items occur at Tier 3 when individual nodes or edges fail schema validation; these are filtered out but validation continues for remaining valid elements.

### Can validateGraph repair graphs with missing required fields automatically?

Yes, the `autoFixGraph` stage supplies sensible defaults for missing fields and coerces compatible types when possible. For example, missing weights receive default numeric values, null arrays become empty arrays, and string representations of numbers are converted to actual numeric types. All repairs are documented in the returned `issues` array.