ruvnet/ruflo · error

verifyChain not available in JS fallback; use ProofChain.ver

Error message

verifyChain not available in JS fallback; use ProofChain.verifyChain()

What it means

getKernel() silently falls back to a pure-JS kernel when the WASM binary fails to load, and the fallback implements only the hashing primitives. verifyChain() deliberately throws because chain verification requires full envelope parsing, which is already implemented by the ProofChain class — the fallback refuses to duplicate it. Hitting this means you are on the JS fallback path and called a WASM-only method.

Source

Thrown at v3/@claude-flow/guidance/src/wasm-kernel.ts:171

      batchProcess: (ops: BatchOp[]): BatchResult[] => {
        const json = (wasm.batch_process as (s: string) => string)(JSON.stringify(ops));
        try { return JSON.parse(json); } catch { return []; }
      },
    };
  } else {
    // JS fallback — identical outputs, just slower
    kernelInstance = {
      available: false,
      version: 'js-fallback',

      sha256: jsSha256,
      hmacSha256: jsHmacSha256,
      contentHash: jsContentHash,
      signEnvelope: jsHmacSha256,
      verifyChain: () => {
        // Chain verification requires full envelope parsing — not implemented
        // in JS fallback because the ProofChain class already does it.
        throw new Error('verifyChain not available in JS fallback; use ProofChain.verifyChain()');
      },

      scanSecrets: (): string[] => {
        // Gate scanning in JS fallback defers to EnforcementGates class
        throw new Error('scanSecrets not available in JS fallback; use EnforcementGates');
      },
      detectDestructive: (): string | null => {
        throw new Error('detectDestructive not available in JS fallback; use EnforcementGates');
      },

      batchProcess: (): BatchResult[] => {
        throw new Error('batchProcess requires WASM kernel');
      },
    };
  }

  return kernelInstance;
}

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Use ProofChain.verifyChain() instead — it is the canonical pure-JS implementation and works everywhere
  2. Feature-detect first with isWasmAvailable() and branch to the pure-JS path when it returns false
  3. If you need the WASM speedup, fix asset loading: ensure the .wasm file ships with the bundle and the runtime permits WebAssembly

Example fix

// before
const ok = getKernel().verifyChain(chainJson, key); // throws in JS fallback

// after
import { ProofChain } from './proof.js';
const ok = isWasmAvailable()
  ? getKernel().verifyChain(chainJson, key)
  : ProofChain.verifyChain(chainJson, key); // canonical JS implementation
Defensive patterns

Strategy: type-guard

Validate before calling

import { getKernel, isWasmAvailable } from './wasm-kernel.js';
import { ProofChain } from './proof.js';

function verifyAnywhere(chainJson: string, key: string): boolean {
  return isWasmAvailable()
    ? getKernel().verifyChain(chainJson, key)
    : ProofChain.verifyChain(chainJson, key); // canonical pure-JS path
}

Type guard

type FullKernel = WasmKernel & { available: true };
function hasFullKernel(k: WasmKernel): k is FullKernel {
  return k.available === true; // false => 'js-fallback', WASM-only ops throw
}

Try / catch

try {
  ok = kernel.verifyChain(chainJson, key);
} catch (e) {
  if (e instanceof Error && e.message.includes('JS fallback')) {
    ok = ProofChain.verifyChain(chainJson, key); // intentional fallback, not a failure
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling kernel.verifyChain(chainJson, key) on the object returned by getKernel() when tryLoadWasm() returned null — e.g. the .wasm asset is missing from the bundle, the runtime lacks WebAssembly support, or a CSP blocks wasm-unsafeeval.

Common situations: Bundlers (webpack/esbuild config) that fail to emit or resolve the .wasm sidecar asset; edge/serverless runtimes without WebAssembly; strict Content-Security-Policy headers; code written against the WASM feature set then deployed where WASM is unavailable.

Related errors


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