ruvnet/ruflo · error

Invalid registry: missing version

Error message

Invalid registry: missing version

What it means

deserializeRegistry() JSON.parses a serialized PatternRegistry and validates that the parsed object has a truthy top-level `version` field before casting it to PatternRegistry. A payload that parses as valid JSON but lacks `version` — `{}`, a CFP pattern document, a truncated/hand-edited file, or data from an incompatible schema — is rejected. Note JSON.parse errors (malformed JSON) throw separately before this check runs.

Source

Thrown at v3/@claude-flow/cli/src/transfer/store/registry.ts:245

  return updated;
}

/**
 * Serialize registry to JSON
 */
export function serializeRegistry(registry: PatternRegistry): string {
  return JSON.stringify(registry, null, 2);
}

/**
 * Deserialize registry from JSON
 */
export function deserializeRegistry(json: string): PatternRegistry {
  const registry = JSON.parse(json);

  // Validate version
  if (!registry.version) {
    throw new Error('Invalid registry: missing version');
  }

  return registry as PatternRegistry;
}

/**
 * Sign registry with private key
 */
export function signRegistry(registry: PatternRegistry, privateKey: string): PatternRegistry {
  const content = JSON.stringify({
    version: registry.version,
    updatedAt: registry.updatedAt,
    patterns: registry.patterns.map(p => p.cid),
    totalPatterns: registry.totalPatterns,
  });

  // In production: Use actual Ed25519 signing
  const signature = crypto

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Open the JSON and confirm it is a registry document: it needs a top-level `"version"` alongside `"patterns"`/`"updatedAt"` — if it looks like a single pattern, you are passing the wrong file.
  2. Delete the corrupt/cached registry file and re-download it from the registry source (re-run store.initialize() or the discovery step).
  3. If you generate registries yourself, always include the version field (use serializeRegistry() to write, never hand-rolled JSON.stringify of a partial object).
  4. If the file came from an older tool version, regenerate it with the current version rather than hand-patching.

Example fix

// before
const registry = deserializeRegistry(await readFile('cache/registry.json', 'utf8'));
// cache/registry.json = { "patterns": [] } → throws: Invalid registry: missing version

// after
await rm('cache/registry.json');               // drop the bad cache
const ok = await store.initialize();           // re-download a proper registry
if (!ok) throw new Error('registry re-fetch failed');
Defensive patterns

Strategy: type-guard

Validate before calling

import { readFile } from 'node:fs/promises';
const text = await readFile(registryPath, 'utf8');
const parsed: unknown = JSON.parse(text); // malformed JSON throws here, separately
if (!isPatternRegistryLike(parsed)) {
  await rm(registryPath); // drop the bad cache and let discovery re-download
  throw new Error('registry cache was invalid — removed; re-run initialize()');
}

Type guard

function isPatternRegistryLike(v: unknown): v is { version: string; patterns: unknown[] } {
  return typeof v === 'object' && v !== null &&
    typeof (v as { version?: unknown }).version === 'string' && (v as { version?: unknown }).version.length > 0 &&
    Array.isArray((v as { patterns?: unknown }).patterns);
}

Try / catch

try {
  const registry = deserializeRegistry(json);
} catch (err) {
  if (err instanceof SyntaxError) throw new Error('registry file is not valid JSON — re-download it');
  if (err instanceof Error && err.message === 'Invalid registry: missing version') {
    throw new Error('wrong or outdated registry file — expected a serialized PatternRegistry with a version field');
  }
  throw err;
}

Prevention

When it happens

Trigger: (1) Feeding a pattern (CFP) file into a code path expecting a registry file; (2) a cached registry.json edited by hand or truncated by a crashed writer; (3) an empty object or different-schema JSON (e.g. `{ patterns: [] }` written without version); (4) version field present but empty string/falsy.

Common situations: Two file formats (registry vs pattern) sharing .json extension and getting swapped; scripts generating registry files that forgot the version key; partial downloads cached to disk; schema drift between the tool version that wrote the file and the one reading it.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/33c8ae4f3adaad9f. Report an issue: GitHub.