{"record":{"id":"47830b5b72b7c6b3","repo":"apify/crawlee","slug":"compilation-result-is-not-a-function","errorCode":null,"errorMessage":"Compilation result is not a function!","messagePattern":"Compilation result is not a function!","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/playwright-crawler/src/internals/utils/playwright-utils.ts","lineNumber":363,"sourceCode":" * still execute in the main process via prototype manipulation. Therefore you\n * should only use this function to execute sanitized or safe code.\n *\n * Custom context may also be provided using the `context` parameter. To improve security,\n * make sure to only pass the really necessary objects to the context. Preferably making\n * secured copies beforehand.\n */\nexport function compileScript(scriptString: string, context: Dictionary = Object.create(null)): CompiledScriptFunction {\n    const funcString = `async ({ page, request }) => {${scriptString}}`;\n\n    let func;\n    try {\n        func = vm.runInNewContext(funcString, context); // \"Secure\" the context by removing prototypes, unless custom context is provided.\n    } catch (err) {\n        getLog().exception(err as Error, 'Cannot compile script!');\n        throw err;\n    }\n\n    if (typeof func !== 'function') throw new Error('Compilation result is not a function!'); // This should not happen...\n\n    return func;\n}\n\nexport interface InfiniteScrollOptions {\n    /**\n     * How many seconds to scroll for. If 0, will scroll until bottom of page.\n     * @default 0\n     */\n    timeoutSecs?: number;\n\n    /**\n     * How many pixels to scroll down. If 0, will scroll until bottom of page.\n     * @default 0\n     */\n    maxScrollHeight?: number;\n\n    /**","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/playwright-crawler/src/internals/utils/playwright-utils.ts#L345-L381","documentation":"compileScript evaluates a user script string with vm.runInNewContext and expects the evaluation to yield a function (the interception/scrolling routine). If the compiled value is not a function, this defensive error is thrown since the result could never be invoked downstream.","triggerScenarios":"Passing a script string to compileScript (used by interceptRequestCompiler for request interception and infiniteScrollCompiler) that evaluates to a non-function value, e.g. an expression like 'window.scrollTo(0, document.body.scrollHeight)' (a call, not a definition) instead of an arrow/function expression.","commonSituations":"Writing an interception script as an immediately-invoked statement rather than a function; typo causing undefined; script compiled in a context where referenced helpers are stripped, yielding undefined.","solutions":["Ensure the script string is a function expression, e.g. 'async ({ request, continue, respond, abort }) => { ... }' rather than a bare statement or IIFE call.","Log the compiled value locally (evaluating the same string) to confirm it evaluates to typeof 'function'.","Check that the script does not rely on globals removed by the sandboxed context."],"exampleFix":"// before\nconst script = \"window.scrollTo(0, document.body.scrollHeight)\";\n// after\nconst script = \"async ({ page }) => { await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); }\";","handlingStrategy":"validation","validationCode":"// validate before compiling\nconst compiled = new Function(`return (${script})`)();\nif (typeof compiled !== 'function') throw new Error('Script must be a function expression');","typeGuard":"function isCompiledFunction(v: unknown): v is (...args: unknown[]) => unknown {\n    return typeof v === 'function';\n}","tryCatchPattern":"try {\n    const fn = compileScript(script);\n} catch (err) {\n    if ((err as Error).message === 'Compilation result is not a function!') {\n        throw new Error(`Script must evaluate to a function, got: ${script.slice(0, 80)}`);\n    }\n    throw err;\n}","preventionTips":["Write scripts as arrow/function expressions, not statements or IIFE invocations.","Test the script string with eval/new Function locally before feeding it to the crawler.","Avoid depending on globals not present in the sandboxed context."],"tags":["vm-compilation","request-interception","scripting","crawlee"],"backgroundTag":"script-compile-failed","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}