ruvnet/ruflo · error

PatternLearner: unsupported schemaVersion ${decoded.schemaVe

Error message

PatternLearner: unsupported schemaVersion ${decoded.schemaVersion} (expected 1)

What it means

PatternLearner.serialize() stamps snapshots with schemaVersion 1; deserialize() refuses any state whose schemaVersion differs, throwing with the found and expected version. The guard prevents silently loading an incompatible state shape (patterns, clusters, counters) written by another release — deserialization is all-or-nothing, so a bad version must fail before partial state is applied.

Source

Thrown at v3/@claude-flow/neural/src/pattern-learner.ts:510

  /**
   * Restore from a previously-serialized state. Replaces all current state.
   * Event listeners NOT restored — re-register after deserialize() returns.
   */
  deserialize(state: unknown): void {
    const decoded = deepDecode(state) as {
      schemaVersion: number;
      config: PatternLearnerConfig;
      patterns: Map<string, Pattern>;
      clusters: Array<{ clusterId: number; centroid: Float32Array; patternIds: string[] }>;
      patternToCluster: Map<string, number>;
      counters: {
        matchCount: number; totalMatchTime: number;
        extractionCount: number; totalExtractionTime: number;
        evolutionCount: number; totalEvolutionTime: number;
      };
    };
    if (decoded.schemaVersion !== 1) {
      throw new Error(`PatternLearner: unsupported schemaVersion ${decoded.schemaVersion} (expected 1)`);
    }
    this.config = { ...this.config, ...decoded.config };
    this.patterns = decoded.patterns;
    this.clusters = decoded.clusters.map((c) => ({
      clusterId: c.clusterId,
      centroid: c.centroid,
      patternIds: new Set(c.patternIds),
    }));
    this.patternToCluster = decoded.patternToCluster;
    this.matchCount = decoded.counters.matchCount;
    this.totalMatchTime = decoded.counters.totalMatchTime;
    this.extractionCount = decoded.counters.extractionCount;
    this.totalExtractionTime = decoded.counters.totalExtractionTime;
    this.evolutionCount = decoded.counters.evolutionCount;
    this.totalEvolutionTime = decoded.counters.totalEvolutionTime;
  }

  // ==========================================================================

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Regenerate the snapshot with the current version (serialize() again after a clean learn cycle)
  2. Pin the library version that wrote the file, load it, migrate the state, re-serialize, then upgrade
  3. Check state.schemaVersion === 1 before deserialize() and route older/newer files to a migration path

Example fix

// before
learner.deserialize(JSON.parse(fs.readFileSync(path, 'utf8')));

// after
const state = JSON.parse(fs.readFileSync(path, 'utf8'));
if (state?.schemaVersion !== 1) {
  throw new Error(`Snapshot schema ${state?.schemaVersion} unsupported - regenerate or migrate it`);
}
learner.deserialize(state);
Defensive patterns

Strategy: validation

Validate before calling

const state = JSON.parse(fs.readFileSync(path, 'utf8')) as { schemaVersion?: number };
if (state?.schemaVersion !== 1) {
  throw new Error(`Snapshot schema ${state?.schemaVersion} unsupported (expected 1) - regenerate or migrate`);
}
learner.deserialize(state);

Type guard

function isV1Snapshot(s: unknown): s is { schemaVersion: 1 } {
  return !!s && typeof s === 'object' && (s as { schemaVersion?: unknown }).schemaVersion === 1;
}

Prevention

When it happens

Trigger: Loading a snapshot produced by a newer/older @claude-flow/neural whose serialize() format changed; hand-edited JSON state files; feeding a ReasoningBank or SONAManager snapshot into PatternLearner.deserialize().

Common situations: Upgrading the package across a schema change and reusing persisted state; several services sharing state files while pinned to different versions.

Related errors


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