{"record":{"id":"6dbc9d91d34ec25f","repo":"apify/crawlee","slug":"compilation-result-is-not-a-function-6dbc9d","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/puppeteer-crawler/src/internals/utils/puppeteer_utils.ts","lineNumber":477,"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\n/**\n * Extended version of Puppeteer's `page.goto()` allowing to perform requests with HTTP method other than GET,\n * with custom headers and POST payload. URL, method, headers and payload are taken from\n * request parameter that must be an instance of Request class.\n *\n * *NOTE:* In recent versions of Puppeteer using requests other than GET, overriding headers and adding payloads disables\n * browser cache which degrades performance.\n *\n * @param page Puppeteer [`Page`](https://pptr.dev/api/puppeteer.page) object.\n * @param request\n * @param [gotoOptions] Custom options for `page.goto()`.\n */\nexport async function gotoExtended(\n    page: Page,","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/puppeteer-crawler/src/internals/utils/puppeteer_utils.ts#L459-L495","documentation":"compileScript() evaluates a string of JavaScript via vm.runInNewContext() and expects the result to be a callable function. This error means the script string evaluated successfully but returned something other than a function (e.g. an object, number, or undefined). The library uses the result as a request interceptor/handler, so a non-function is unusable and the code throws defensively ('This should not happen...').","triggerScenarios":"Calling compileScript (directly or via page.setRequestInterception helpers) with a script string whose body evaluates to a non-function value — e.g. the string is a bare expression like '1+1', an object literal, an async arrow missing parentheses, or the script was truncated so the function declaration never completes.","commonSituations":"Users storing interception scripts in files/env vars that get mangled (quotes stripped, newlines lost), passing a snippet copied as an expression instead of a function definition, or upgrading Crawlee where compileScript previously tolerated non-function results.","solutions":["Ensure the script string evaluates to a function, e.g. '() => { ... }' or 'async function intercept(request) { ... }'","Log the evaluated result (typeof vm.runInNewContext(script)) during development to confirm it is 'function'","Check the script source for truncation or escaping problems (quotes, template literals) when loading from config/env","If the script intentionally returns a value, wrap it: '(' + expression + ')' and verify it returns a callable"],"exampleFix":"// before\nawait page.setRequestInterception(compileScript('request.continue()'));\n// after\nawait page.setRequestInterception(compileScript('async ({ request }) => { await request.continue(); }'));","handlingStrategy":"validation","validationCode":"function isScriptAFunction(src) {\n    try {\n        const sandbox = { console };\n        return typeof require('vm').runInNewContext(src, sandbox) === 'function';\n    } catch { return false; }\n}\nif (!isScriptAFunction(myScript)) throw new TypeError('interception script must evaluate to a function');","typeGuard":"const isFn = (v) => typeof v === 'function';","tryCatchPattern":"try {\n    const func = compileScript(script);\n} catch (err) {\n    log.error('script did not compile to a function', { script: script.slice(0, 200) });\n    throw err;\n}","preventionTips":["Always author interception scripts as function expressions, e.g. 'async ({ request }) => { ... }'","Smoke-test scripts in a vm sandbox before deploying","Avoid loading scripts from loosely-validated env/config where quoting can break","Unit-test compileScript output type in CI"],"tags":["puppeteer","javascript","vm","configuration"],"backgroundTag":"script-eval-non-function","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}