How Modly Validates Extension Manifests: A Complete Technical Guide

Modly validates extension manifests through a three-stage pipeline that detects the manifest file, performs integrity checks for completion and JSON validity, and applies semantic normalization including trusted-source verification and field augmentation.

The lightningpixel/modly repository implements a robust validation system for extension manifests that ensures only properly structured and trustworthy extensions load into the application. Every time Modly discovers an extension folder—whether for built-in extensions or user-installed packages—it executes a rigorous validation sequence defined primarily in electron/main/ipc-handlers.ts. Understanding this pipeline is essential for developers building Modly-compatible extensions or debugging installation issues.

The Three-Stage Validation Pipeline

Modly's manifest validation occurs whenever the extensions:list IPC handler scans the extensions directory. The process breaks down into distinct detection, integrity, and semantic phases.

Stage 1: Manifest Detection and Loading

The validation begins in the extensions:list handler located at electron/main/ipc-handlers.ts (lines 89-101). For each folder in the extensions directory, the system iterates through ['manifest.json', 'package.json'] to locate a manifest file. The first existing file is read as UTF-8 text and parsed using JSON.parse() into a ParsedManifest object.

If a manifest.json exists alongside legacy package.json files, Modly prioritizes the modern manifest format. The system also checks for a local source injection (local://) for extensions installed from local paths, enabling development workflows without registry requirements.

Stage 2: Basic Integrity Checks

Before parsing content, Modly verifies the extension's installation state and file integrity (lines 90-106). The system performs three critical checks:

  • Incomplete installation: If the hidden .modly-incomplete marker exists, validation returns manifestError: 'incomplete', indicating the installation never finished.
  • Missing manifest: When neither manifest.json nor package.json exists, the error status becomes 'missing'.
  • Invalid JSON: If JSON.parse() throws an exception, the system sets manifestError: 'invalid' and continues to the next extension.

Only manifests passing these checks proceed to semantic validation through the parseExtensionManifest function.

Stage 3: Semantic Validation and Augmentation

The parseExtensionManifest routine (lines 11-44) transforms raw JSON into a strongly-typed extension description through systematic normalization:

  • ID fallback: Assigns a fallbackId when the manifest omits an explicit id field.
  • Display name resolution: Derives the display name using the precedence displayName → name → fallbackId.
  • Type enforcement: Ensures the type field equals either "model" or "process"; for "process" types, defaults the entry field to processor.js.
  • Node normalization: Supplies default input ("image") and output ("mesh") values, merges node-level and extension-level params_schema and param_defaults, and copies Hugging Face-related fields.

If required fields like nodes are missing or empty, the function throws an explicit error: throw new Error('manifest.json: required field "nodes" missing or empty').

Trusted Source Verification

Modly implements security-based validation through the fetchTrustedRepos() and isTrustedSource() functions. The system downloads the official extensions registry from https://raw.githubusercontent.com/lightningpixel/modly-official-extension/main/registry.json, normalizes URLs (lowercased, trailing slashes removed), and caches the result for five minutes.

During validation, isTrustedSource(source, trustedRepos) performs a set lookup against these trusted repositories. Built-in extensions automatically receive trusted status regardless of their source URL. This distinction determines whether Modly applies additional security restrictions or allows full extension capabilities.

Error Handling and User Feedback

Validation errors propagate through the IPC layer to the UI components. The ExtensionDrawer.tsx component (located in src/areas/models/components/) interprets manifestError values—missing, invalid, or incomplete—and renders user-friendly messages explaining why an extension failed to load.

For installation-time validation, electron/main/extension-install-utils.ts performs additional mandatory field checks (id, type, entry) when users install extensions from GitHub, preventing corrupted packages from entering the extensions directory.

Practical Validation Examples

Retrieve validated extensions through the IPC renderer:

// Returns fully-validated manifests or objects with manifestError descriptions
const extensions = await ipcRenderer.invoke('extensions:list');

Manually validate a manifest file for testing purposes:

import { readFile } from 'fs/promises';
import { parseExtensionManifest } from './electron/main/ipc-handlers';

async function validateManifest(path: string, fallbackId: string) {
  const raw = await readFile(path, 'utf-8');
  const parsed = JSON.parse(raw);
  const trustedRepos = new Set<string>(); // Empty set means untrusted
  return parseExtensionManifest(parsed, fallbackId, trustedRepos, false);
}

The scripts/build-builtins.mjs script ensures built-in extensions include proper manifest.json files during the build process, guaranteeing the validator always encounters well-formed manifests for core extensions.

Summary

  • Three-stage pipeline: Modly validates manifests through detection (finding manifest.json or package.json), integrity checks (incomplete markers and JSON validity), and semantic enrichment (field normalization and type enforcement).
  • Trusted sources: Extensions become trusted either by being built-in or by matching URLs in the cached official registry fetched from the modly-official-extension repository.
  • Error propagation: The system surfaces specific error types (missing, invalid, incomplete) to the UI, while throwing exceptions for critical schema violations like empty nodes arrays.
  • Implementation location: Core validation logic resides in electron/main/ipc-handlers.ts, with supplementary installation checks in electron/main/extension-install-utils.ts.

Frequently Asked Questions

What files does Modly look for when validating an extension?

Modly searches for manifest.json first, then falls back to legacy package.json. The validation occurs in electron/main/ipc-handlers.ts within the extensions:list IPC handler, which scans both the user extensions directory and the built-in extensions folder.

How does Modly handle corrupted or incomplete extension installations?

If the .modly-incomplete marker file exists in the extension directory, Modly marks the manifest with manifestError: 'incomplete'. For unparseable JSON, it returns manifestError: 'invalid', and when no manifest exists, it returns manifestError: 'missing'. The UI component ExtensionDrawer.tsx translates these codes into user-friendly error messages.

What makes an extension "trusted" in Modly?

An extension gains trusted status through two mechanisms: being a built-in extension (automatic trust), or having its source URL match an entry in the official registry fetched from https://raw.githubusercontent.com/lightningpixel/modly-official-extension/main/registry.json. The fetchTrustedRepos() function caches these trusted URLs for five minutes to optimize performance.

Which manifest fields are required for a Modly extension to load successfully?

The manifest must include a nodes array with at least one entry. For process-type extensions, the type field must equal "process" and the entry field (defaulting to processor.js) must specify the processor script. The system also requires valid name or displayName fields, and enforces that type must be either "model" or "process".

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →