{"record":{"id":"87b6a79041e20429","repo":"GitbookIO/gitbook","slug":"invalid-nodes-found-when-parsing","errorCode":null,"errorMessage":"Invalid nodes found when parsing","messagePattern":"Invalid nodes found when parsing","errorType":"exception","errorClass":"ExpressionError","httpStatus":null,"severity":"error","filePath":"packages/expr/src/runtime.ts","lineNumber":48,"sourceCode":"        this.#parserOptions = {\n            ecmaVersion: 'latest',\n            sourceType: 'script',\n            allowHashBang: false,\n            locations: true,\n        };\n        this.#autocompleter = new AutoComplete(this, logger);\n        this.#logger = logger;\n    }\n\n    /**\n     * Evaluates an expression based on the given inputs/context.\n     */\n    public evaluate(expr: string, inputs: object): unknown {\n        try {\n            const parsed = this.parse(expr);\n\n            if (parsed.invalidNodes.length > 0) {\n                throw new ExpressionError('Invalid nodes found when parsing');\n            }\n\n            return evaluate.sync<Expression>(parsed.result, inputs, {\n                functions: true,\n                withMembers: true,\n                generate: escodegen.generate,\n            });\n        } catch (error) {\n            throw error instanceof Error\n                ? new ExpressionError(error.message)\n                : new ExpressionError('Unexpected error');\n        }\n    }\n\n    /**\n     * Evaluates an expression safely by returning the error instead of throwing when invalid.\n     */\n    public safeEvaluate(","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/GitbookIO/gitbook/blob/db67585ee243d063c459a855988f21612cea9c95/packages/expr/src/runtime.ts#L30-L66","documentation":"Thrown by ExpressionRuntime.evaluate in @gitbook/expr when jexpr parses the expression successfully but reports invalid nodes. This means the syntax was consumed by the lenient parser yet contains constructs the evaluator cannot compile, so evaluation is aborted rather than producing a wrong value.","triggerScenarios":"Calling evaluate() with expressions containing unsupported syntax (novel ES constructs, unusual operators, or malformed fragments that only the error-tolerant parser accepts); expressions with stray tokens like 'a + + b' or incomplete member chains.","commonSituations":"User-authored expressions (filters, computed values) fed from a CMS or visual editor; copy-pasted JS snippets with syntax the evaluator's AST whitelist rejects; upgrading @gitbook/expr or its parser deps enabling new parse paths that now surface invalid nodes.","solutions":["Run runtime.parse(expr) or getVariables(expr) as a pre-flight to detect invalid nodes before evaluating user input","Simplify the expression to basic operators, member access, and literals that the evaluator supports","If input is user-provided, validate/sanitize expressions and show an editor error instead of evaluating","Report the expression to the @gitbook/expr maintainers if it's plain JS that should work"],"exampleFix":"// before\nconst result = runtime.evaluate('user. + 1', inputs);\n\n// after\nconst result = runtime.evaluate('user.count + 1', inputs);","handlingStrategy":"try-catch","validationCode":"const parsed = runtime.parse(expr);\nif (parsed.invalidNodes.length > 0) {\n    return fallbackValue;\n}","typeGuard":null,"tryCatchPattern":"try {\n    return runtime.evaluate(expr, inputs);\n} catch (error) {\n    if (error instanceof ExpressionError) {\n        return fallbackValue; // or surface to the editor\n    }\n    throw error;\n}","preventionTips":["Pre-flight parse user expressions and check invalidNodes","Restrict the expression grammar exposed in your UI","Show validation errors in the editor before submission"],"tags":["expression","parsing","expr","evaluation"],"backgroundTag":"expression-parse-error","analyzedSha":"db67585ee243d063c459a855988f21612cea9c95","analyzedAt":"2026-08-28T17:49:47.831Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}