gchq/CyberChef · error · OperationError

Invalid Jsonata Expression: ${err.message}

Error message

Invalid Jsonata Expression: ${err.message}

What it means

Thrown by JSONata when either the expression fails to compile (jsonata(query)) or its evaluation throws (expression.evaluate(jsonObj)). The catch wraps both compile-time and runtime JSONata errors into a single message.

Source

Thrown at src/core/operations/Jsonata.mjs:68

        }

        try {
            const expression = jsonata(query);
            // Override built-in base64 functions which fail in Web Worker
            // context where `window` is undefined. The jsonata library falls
            // back to `global.Buffer` which also does not exist in workers.
            // `atob`/`btoa` are available in both browser and worker scopes.
            expression.registerFunction("base64decode", (str) => {
                if (typeof str === "undefined") return undefined;
                return atob(str);
            }, "<s-:s>");
            expression.registerFunction("base64encode", (str) => {
                if (typeof str === "undefined") return undefined;
                return btoa(str);
            }, "<s-:s>");
            result = await expression.evaluate(jsonObj);
        } catch (err) {
            throw new OperationError(
                `Invalid Jsonata Expression: ${err.message}`
            );
        }

        return JSON.stringify(result === undefined ? "" : result);
    }
}

export default JsonataQuery;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Split compile vs evaluate: call jsonata(query) separately to isolate a syntax error from a runtime one.
  2. Test the expression in the JSONata Exerciser with the same payload.
  3. Guard runtime paths with $exists() and '?' optional-axis operators.
  4. Avoid functions the Web Worker context does not expose (the operation already overrides base64).

Example fix

// before: unguarded access on missing field
'$account.balance'
// after: existence guard
'($exists($account) ? $account.balance : 0)'
Defensive patterns

Strategy: try-catch

Validate before calling

function compileJsonata(query) {
  try { return jsonata(query); }
  catch (e) { throw new Error(`JSONata compile error: ${e.message}`); }
}

Type guard

function isCompilableJsonata(q) {
  try { jsonata(q); return true; } catch { return false; }
}

Try / catch

try {
  return await chef.Jsonata(json, { query });
} catch (e) {
  if (/Invalid Jsonata Expression/.test(e.message))
    throw new Error('Split compile vs evaluate and test in the JSONata Exerciser');
  throw e;
}

Prevention

When it happens

Trigger: Compile errors: unbalanced parentheses, invalid JSONata syntax, undefined/typo'd function names. Runtime errors during evaluate: division by zero, type mismatches, referencing a function the sandbox does not expose, or errors raised by the expression's own $error() calls.

Common situations: Iterating JSONata syntax from another query language. Using a JSONata function not present in the bundled version. Expressions that assume a data shape the input does not match.

Understand the failure class

Related errors


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