ruvnet/ruflo · error · Error

Invalid CFP file: ${e instanceof Error ? e.message : String(

Error message

Invalid CFP file: ${e instanceof Error ? e.message : String(e)}

What it means

deserializeCFP(data) first runs JSON.parse over the entire input (string or utf-8-decoded Buffer). When parsing fails it wraps the underlying SyntaxError message into 'Invalid CFP file: ...' — so this specifically means the bytes are not valid JSON at all, before any CFP-specific validation (magic bytes, schema) happens. The wrapped message usually pinpoints the JSON syntax problem (unexpected token, position).

Source

Thrown at v3/@claude-flow/cli/src/transfer/serialization/cfp.ts:148

    case 'cbor.zstd':
    case 'msgpack':
      throw new Error(`Serialization format '${format}' is not implemented. Use 'json' instead.`);
    default:
      return Buffer.from(json, 'utf-8');
  }
}

/**
 * Deserialize CFP from string/buffer
 */
export function deserializeCFP(data: string | Buffer): CFPFormat {
  const str = typeof data === 'string' ? data : data.toString('utf-8');

  let parsed: CFPFormat;
  try {
    parsed = JSON.parse(str);
  } catch (e) {
    throw new Error(`Invalid CFP file: ${e instanceof Error ? e.message : String(e)}`);
  }

  // Validate magic bytes
  if (parsed.magic !== 'CFP1') {
    throw new Error(`Invalid CFP format: expected magic 'CFP1', got '${parsed.magic}'`);
  }

  return parsed;
}

/**
 * Validate CFP document
 */
export function validateCFP(cfp: CFPFormat): { valid: boolean; errors: string[] } {
  const errors: string[] = [];

  if (cfp.magic !== 'CFP1') {
    errors.push(`Invalid magic bytes: ${cfp.magic}`);

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Inspect the wrapped message — it names the exact JSON syntax error and position; open the file at that offset
  2. Validate the source is intact: re-fetch the CFP by CID, check file size, or JSON.parse it directly in a scratch script
  3. If the payload is not meant to be JSON (e.g. compressed), decode/decompress before deserializeCFP
  4. For empty files, the producer side failed — regenerate/export the CFP

Example fix

// before
const cfp = deserializeCFP(await fs.readFile('pattern.cfp.json')); // truncated file -> Invalid CFP file: Unexpected end of JSON input

// after
const raw = await fs.readFile('pattern.cfp.json', 'utf-8');
let cfp;
try {
  cfp = deserializeCFP(raw);
} catch (e) {
  if (/Invalid CFP file/.test(String(e?.message))) {
    console.error('CFP payload is not valid JSON (first 200 chars):', raw.slice(0, 200));
    throw e; // or re-fetch the file by CID
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Cheap pre-check: confirm the payload is JSON before handing it to the CFP parser
import * as fs from 'node:fs';
const raw = fs.readFileSync(file, 'utf-8');
try { JSON.parse(raw); } catch {
  throw new Error(`${file} is not valid JSON — refusing to parse as CFP`);
}
const cfp = deserializeCFP(raw);

Try / catch

try {
  const cfp = deserializeCFP(raw);
} catch (e) {
  if (/^Invalid CFP file:/.test(String((e as Error).message))) {
    // syntax-level corruption: log a payload sample for diagnosis, then re-fetch from source
    console.error('Not valid JSON (first 200 bytes):', String(raw).slice(0, 200));
    throw new Error(`CFP file corrupt — re-download by CID: ${file}`);
  }
  throw e; // magic/schema errors have different messages and different remedies
}

Prevention

When it happens

Trigger: Feeding deserializeCFP a truncated file (partial download/transfer), an empty string, a binary/CBOR payload, an HTML error page saved as .cfp.json, or a file with a BOM/encoding corruption.

Common situations: Reading a CFP fetched from a gateway that returned an error page instead of JSON; files truncated by disk-full or interrupted IPFS retrieval; hand-edited JSON with trailing commas; double-encoded or base64-wrapped payloads.

Related errors


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