gchq/CyberChef · error · OperationError

Unable to stringify YAML: ${err}

Error message

Unable to stringify YAML: ${err}

What it means

Thrown by JSON to YAML when js-yaml's dump() cannot serialise the input. The operation expects an already-parsed JSON object (inputType JSON), and dump() fails on values YAML cannot represent: circular references, functions, symbols, or unsupported scalar types under the active schema.

Source

Thrown at src/core/operations/JSONtoYAML.mjs:40

        this.name = "JSON to YAML";
        this.module = "Default";
        this.description = "Format a JSON object into YAML";
        this.infoURL = "https://en.wikipedia.org/wiki/YAML";
        this.inputType = "JSON";
        this.outputType = "string";
        this.args = [];
    }

    /**
     * @param {JSON} input
     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {
        try {
            return dump(input);
        } catch (err) {
            throw new OperationError("Unable to stringify YAML: " + err);
        }
    }

}

export default JSONtoYAML;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Ensure the input is a plain JSON-deserialisable object (no cycles, no functions).
  2. Break circular references (e.g. with a replacer or by removing back-pointers) before dumping.
  3. JSON.stringify then JSON.parse the object first to strip functions/symbols/prototypes.
  4. Pass dump options (noRefs, schema) if calling js-yaml directly.

Example fix

// before: cyclic object
const o = {}; o.self = o;
chef.JSONtoYAML(o);
// after: acyclic plain object
const clean = JSON.parse(JSON.stringify({ a: 1, b: [2, 3] }));
chef.JSONtoYAML(clean);
Defensive patterns

Strategy: validation

Validate before calling

function safeForYaml(obj) {
  const seen = new WeakSet();
  (function walk(v) {
    if (v === null || typeof v !== 'object') return;
    if (seen.has(v)) throw new Error('Circular reference detected');
    seen.add(v);
    Object.values(v).forEach(walk);
  })(obj);
  return JSON.parse(JSON.stringify(obj));
}

Type guard

function isPlainSerializable(obj) {
  const seen = new WeakSet();
  function ok(v) {
    if (v === null || typeof v !== 'object') return typeof v !== 'function';
    if (seen.has(v)) return false;
    seen.add(v);
    return Object.values(v).every(ok);
  }
  return ok(obj);
}

Try / catch

try {
  return chef.JSONtoYAML(obj);
} catch (e) {
  if (/Unable to stringify YAML/.test(e.message))
    throw new Error('Object has cycles/functions - strip them before YAML export');
  throw e;
}

Prevention

When it happens

Trigger: Passing an object with a circular reference (a.b = a). An object containing a function, BigInt, or class instance. Extremely deep nesting exceeding js-yaml's limits. Passing a primitive string/number where a parsed object is expected (dump of a string succeeds, so the failure is specifically on un-serialisable structure).

Common situations: Decoding JSON then mutating the result into a cyclic graph before conversion. Using a custom class instance instead of a plain object. Hand-constructed objects with non-data members.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/4899ae9f0a3293e2. Report an issue: GitHub.