# How to Debug Archify Rendering Failures Using Diagnostic Error Codes: A Complete Guide

> Debug Archify rendering failures fast with diagnostic error codes. Analyze root causes precisely using structured error data from tt-a1i/archify for quicker fixes.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: how-to-guide
- Published: 2026-08-03

---

**Archify captures every rendering failure as a structured diagnostic object containing a unique slash-separated error code, severity flag, subject reference, and actionable fixes, enabling precise root-cause analysis without stack-trace ambiguity.**

Archify’s rendering pipeline replaces vague JavaScript stack traces with a **structured diagnostic system** that assigns a machine-readable code to every failure. When the engine encounters an invalid schema, a symlink cycle, or a layout overflow, it generates rich error objects that pinpoint exactly which artifact caused the problem and how to fix it. Learning to debug archify rendering failures using diagnostic error codes allows you to resolve complex data-flow and layout graphs efficiently, turning opaque crashes into actionable remediation steps.

## Understanding the Archify Diagnostic Architecture

The diagnostic system is implemented across several specialized modules in the `tt-a1i/archify` repository. Each component normalizes, validates, or reports errors using a consistent schema.

**`archify/renderers/shared/diagnostics.mjs`** serves as the core utility module. It exports `recordDiagnostic` to normalize diagnostic objects and `throwDiagnosticError(message, diagnostics)` to attach the full diagnostic array to `error.archifyDiagnostics` before throwing.

**`archify/renderers/shared/validator.mjs`** converts JSON-Schema validation failures into Archify diagnostics. When an input contains unexpected properties, this module generates codes like `schema/additionalProperties` with the violating key as evidence.

**`archify/renderers/shared/output-path.mjs`** handles filesystem-related diagnostics. It emits codes such as `output/symlink-cycle` or `output/input-alias` when the output directory contains recursive symlinks or when the render target aliases its own input.

**Individual renderers** (e.g., `archify/renderers/workflow/render-workflow.mjs`) call `throwDiagnosticProblems` when encountering unrecoverable states like `legend/vertical-overflow` or `artifact/single-svg`.

**The CLI entry point** at `archify/bin/archify.mjs` catches these exceptions, prints human-readable summaries, and writes the full [`diagnostics.json`](https://github.com/tt-a1i/archify/blob/main/diagnostics.json) file when the `--json` flag is provided.

### The Diagnostic Lifecycle

Every failure flows through five standardized stages:

1. **Detection** – A renderer or utility detects an illegal condition, such as a circular symlink or schema violation.
2. **Normalization** – The component calls `recordDiagnostic`, which ensures every entry includes a `code` (defaulting to `internal/unclassified` if missing), `severity`, `subject`, `evidence`, and `supportedFixes`.
3. **Throwing** – The code invokes `throwDiagnosticError(message, diagnostics)`, which attaches the normalized array to the error object’s `archifyDiagnostics` property.
4. **Propagation** – The exception bubbles up through the renderer chain to the CLI or API boundary.
5. **Reporting** – The CLI prints a concise line like `⚠️ output/symlink-cycle` and, if requested, serializes the full array to JSON.

## Step-by-Step Debugging Workflow

To debug archify rendering failures using diagnostic error codes, follow this systematic approach:

1. **Execute the render command** and observe the short code printed to stderr:

   ```bash
   npx archify render diagram.json --output out/
   ```

   On failure, Archify outputs:
   ```

   ✖ Rendering failed (output/symlink-cycle)
   ⤷ See diagnostics.json for details.
   ```

2. **Inspect the diagnostic dump**. If running programmatically, catch the error and read `err.archifyDiagnostics`. If using the CLI, add the `--json` flag:

   ```bash
   npx archify render diagram.json --output out/ --json > diagnostics.json
   ```

   A typical entry contains:
   ```json
   {
     "code": "output/symlink-cycle",
     "severity": "error",
     "subject": { "output": "out/diagram.html" },
     "evidence": { "cycle": ["/a", "/b", "/a"] },
     "supportedFixes": ["Remove the symlink that creates the cycle"]
   }
   ```

3. **Map the code prefix to the source module**. The namespace before the slash indicates the origin:
   - `output/` → `output-path.mjs`
   - `schema/` → `validator.mjs`
   - `legend/`, `artifact/`, `engineering/` → Specific renderer implementations

4. **Apply the suggested fix**. The `supportedFixes` array provides actionable remediation, such as "Remove the duplicate SVG" for `artifact/single-svg` or "Add unique IDs" for `delta/relationship-id-required`.

5. **Re-run Archify** to verify the diagnostic clears.

## Common Diagnostic Codes and Resolutions

| Code | Meaning | Typical Fix |
|------|---------|-------------|
| **output/symlink-cycle** | A symlink loop exists in the output directory. | Delete or break the problematic symlink. |
| **output/input-alias** / **output/target-alias** | The render target aliases its own input, causing recursion. | Use a distinct filename for the output. |
| **schema/additionalProperties** | JSON-Schema validation found an unexpected property. | Remove the stray key or update the schema. |
| **legend/vertical-overflow** | Legend entries exceed available vertical space. | Increase legend height or truncate entries. |
| **engineering/deployment-crossing-mechanism** | Conflicting deployment mechanisms in an engineering profile. | Align mechanisms or split the profile. |
| **artifact/single-svg** | Expected exactly one SVG artifact but found zero or multiple. | Ensure the source diagram produces a single SVG. |
| **delta/relationship-id-required** | Relationship objects in a delta file lack an `id` field. | Add unique IDs to each relationship. |

## Programmatic Error Handling

### Catching Diagnostics in Node.js

When embedding Archify in a Node.js application, access the diagnostic array via the error object:

```javascript
import { renderWorkflow } from './archify/renderers/workflow/render-workflow.mjs';

try {
  await renderWorkflow('input.workflow.json', 'out/rendered.html');
} catch (err) {
  console.error('Rendering failed:', err.message);
  
  for (const d of err.archifyDiagnostics || []) {
    console.error(` • ${d.code} – ${d.subject?.output ?? 'unknown'}`);
    console.error(`   Evidence: ${JSON.stringify(d.evidence)}`);
    console.error(`   Fixes: ${d.supportedFixes?.join('; ')}`);
  }
}

```

### Generating JSON Reports via CLI

For CI pipelines or automated inspection, request structured output:

```bash

# Full diagnostic dump

npx archify render complex-diagram.json --output ./build --json > diagnostics.json

# Inspect specific codes

cat diagnostics.json | jq '.[] | select(.code | startswith("output/"))'

```

### Validating Render Output in Tests

The `checkRenderOutput` utility used by the Archify test suite returns a receipt containing all diagnostics:

```javascript
import { checkRenderOutput } from './archify/scripts/check-render-output.mjs';

const receipt = await checkRenderOutput('out/diagram.html');
receipt.diagnostics.forEach(d => {
  if (d.severity === 'error') {
    console.error(`Blocking issue: ${d.code}`);
    console.error(`Context: ${JSON.stringify(d.evidence)}`);
  }
});

```

## Summary

- **Archify diagnostic codes** follow a `namespace/specific-issue` format (e.g., `output/symlink-cycle`), allowing immediate identification of the failing subsystem.
- **Rich error objects** include `subject` (the offending artifact), `evidence` (contextual data), and `supportedFixes` (actionable remediation steps).
- **Key source files** for debugging are `diagnostics.mjs` (normalization), `validator.mjs` (schema errors), and `output-path.mjs` (filesystem issues).
- **Programmatic access** requires reading `error.archifyDiagnostics` after catching exceptions from render functions.
- **CLI debugging** uses the `--json` flag to export the full diagnostic array for inspection or CI processing.

## Frequently Asked Questions

### What is the format of an Archify diagnostic code?

Archify diagnostic codes use a hierarchical `namespace/specific-issue` format, such as `schema/additionalProperties` or `legend/vertical-overflow`. The prefix maps directly to the source module: `output/` indicates filesystem issues in `output-path.mjs`, while `schema/` indicates validation errors from `validator.mjs`.

### Where are diagnostic codes defined in the source code?

Diagnostic codes are generated dynamically throughout the codebase rather than centralized in an enum. The `recordDiagnostic` function in `archify/renderers/shared/diagnostics.mjs` normalizes codes and defaults to `internal/unclassified` if none is provided. Specific codes like `output/symlink-cycle` originate in `output-path.mjs`, while renderer-specific codes (e.g., `artifact/single-svg`) are thrown by individual renderers like `render-workflow.mjs`.

### How do I access the full diagnostic array programmatically?

When calling Archify render functions from JavaScript, wrap the call in a try-catch block and inspect `err.archifyDiagnostics`. This property contains the complete array of normalized diagnostic objects, each with `code`, `severity`, `subject`, `evidence`, and `supportedFixes` fields.

### Can I configure which diagnostic severities cause a failure?

Currently, the Archify CLI treats all diagnostics with `severity: "error"` as fatal and exits with a non-zero status. Warnings (`severity: "warning"`) are printed but do not halt execution. There is no built-in flag to suppress specific codes, but you can filter the JSON output post-render using tools like `jq` to ignore known acceptable warnings in your pipeline.