Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The error means your code is calling executablePath with the wrong API shape for the installed @sparticuz/chromium version. Current releases expose chromium.executablePath(location?) as a function, so use await chromium.executablePath(). Older releases exposed executablePath as a promise-returning getter, so the correct form was await chromium.executablePath. Check the package actually deployed to Lambda, then fix your CDK bundling or layer configuration so only the intended copy is loaded.

Start with the correct call syntax

Use the form that matches the installed package and its TypeScript declarations:

Current function-style API

const executablePath = await chromium.executablePath();

const browser = await puppeteer.launch({
  args: chromium.args,
  defaultViewport: chromium.defaultViewport,
  executablePath,
  headless: chromium.headless,
});

Older getter-style API

const executablePath = await chromium.executablePath;

const browser = await puppeteer.launch({
  args: chromium.args,
  defaultViewport: chromium.defaultViewport,
  executablePath,
  headless: chromium.headless,
});

Do not choose between these forms by copying an old blog post. Confirm the version that is installed in the Lambda asset with npm ls @sparticuz/chromium and by inspecting package-lock.json (or your equivalent lockfile). Read that release’s README and declaration file. If CDK bundles the module, inspect the generated bundle as well: esbuild interop, a stale Lambda layer, or a duplicate package can make the runtime export differ from your local source.

Why “is not a function” appears

JavaScript throws this TypeError when a value is called with parentheses even though it is not callable. In the older package API, chromium.executablePath was already a promise. Adding () attempted to invoke that promise as a function. In the current API, the property is a function that returns a promise, so omitting parentheses leaves you with the function itself rather than the resolved path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
  • Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
  • Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
  • CanaKit Turbine Black Case for the Raspberry Pi 5
  • CanaKit Low Noise Bearing System Fan
  • Mega Heat Sink - Black Anodized

The error can therefore survive a source-code change when Lambda is loading another copy. Common causes include a layer that still contains an older release, a bundled copy alongside the layer copy, or a deployment asset that was not rebuilt after changing dependencies.

Verify what Lambda is really loading

  1. Resolve the dependency tree. Run npm ls @sparticuz/chromium from the application directory. Multiple versions are a warning sign.
  2. Check the lockfile. Confirm the exact version selected for production installation, not merely the version range in package.json.
  3. Check the deployed asset. For a bundled function, inspect the generated JavaScript or deployment archive. For a layer, inspect the layer archive and its package metadata.
  4. Inspect the export shape in a diagnostic deployment. A temporary log such as console.log(typeof chromium.executablePath) tells you whether Lambda sees a function or another value. Log the resolved path once, then remove or restrict the diagnostic.

Keep @sparticuz/chromium in dependencies when the function needs it at runtime. A devDependency may be omitted from a production install and leave the deployed function without the module or its binary.

Choose one CDK packaging model

A reliable deployment has one deliberate source for the Chromium package. Either bundle it with the function or provide it through a Lambda layer. Mixing both models accidentally is a frequent reason local code and Lambda behave differently.

Decision point Bundle with the function Provide through a layer
Deployment package Contains the module and its Chromium assets with each function. Function package is smaller; the layer carries the shared files.
Sharing Each function has its own copy. Several functions can use one attached layer.
Version synchronization Version follows the function’s lockfile and bundle. You must keep the layer’s package compatible with the function code.
CDK configuration Do not externalize @sparticuz/chromium. Set externalModules: ['@sparticuz/chromium'] when the layer supplies it.
Cold-start behavior Chromium assets are extracted from the function deployment. Layer assets are mounted under /opt and may still need extraction by the package.
Local reproduction Usually simpler because the function bundle contains its dependency. Requires reproducing the layer path and attachment when testing packaging.

Bundle @sparticuz/chromium with NodejsFunction

CDK’s NodejsFunction bundles referenced modules with esbuild by default. Keep the package in runtime dependencies and do not list it as external when the function is meant to contain it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import * as path from 'node:path';
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as nodejs from 'aws-cdk-lib/aws-lambda-nodejs';

const fn = new nodejs.NodejsFunction(this, 'PdfFn', {
  entry: path.join(__dirname, '../src/handler.ts'),
  runtime: lambda.Runtime.NODEJS_20_X,
  architecture: lambda.Architecture.X86_64,
  // No externalModules entry for @sparticuz/chromium:
  // esbuild includes the runtime dependency.
});

After changing the dependency version, rebuild and redeploy the function asset. Remove old generated assets from your build process if your CI system caches them; otherwise a successful CDK deployment can still contain the previous export shape.

Rank #2
CanaKit Raspberry Pi 4 4GB Starter PRO Kit - 4GB RAM
  • Includes Raspberry Pi 4 4GB Model B with 1.5GHz 64-bit quad-core CPU (4GB RAM)
  • Includes Pre-Loaded 32GB EVO+ Micro SD Card (Class 10), USB MicroSD Card Reader
  • CanaKit Premium High-Gloss Raspberry Pi 4 Case with Integrated Fan Mount, CanaKit Low Noise Bearing System Fan
  • CanaKit 3.5A USB-C Raspberry Pi 4 Power Supply (US Plug) with Noise Filter, Set of Heat Sinks, Display Cable - 6 foot (Supports up to 4K60p)
  • CanaKit USB-C PiSwitch (On/Off Power Switch for Raspberry Pi 4)

Put the package in a Lambda layer

A Node.js layer must use Lambda’s expected directory layout. The archive should contain a path such as nodejs/node_modules/@sparticuz/chromium. At runtime Lambda exposes Node.js layer modules under /opt/nodejs/node_modules.

const fn = new nodejs.NodejsFunction(this, 'PdfFn', {
  entry: 'src/handler.ts',
  runtime: lambda.Runtime.NODEJS_20_X,
  architecture: lambda.Architecture.X86_64,
  layers: [chromiumLayer],
  bundling: {
    externalModules: ['@sparticuz/chromium'],
  },
});

Use externalModules only when the attached layer really supplies the package. If the layer is missing, incorrectly laid out, or not attached to the deployed function, externalization removes the bundled fallback and produces a module or binary error. Conversely, leaving a layer-supplied module bundled can create two copies with different versions.

The Chromium package documentation also describes passing an explicit extraction location when your layer design requires it:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const executablePath = await chromium.executablePath('/opt/chromium');

Use that location only when the binary assets are actually available there and the installed release supports the argument.

Use the supported Lambda architecture

The documented Chromium build does not support ARM. Set the CDK architecture explicitly to Architecture.X86_64 unless the exact package release you selected documents ARM support. An ARM64 deployment can fail with an execution-format error before Puppeteer starts; switching the function and compatible layer to x86_64 resolves that class of failure.

Rank #3
ELECROW CrowPi Case Kit for Raspberry Pi 5, 9-Inch Display
  • Not including the Raspberry Pi 5 (8GB), the Crowpi advanced version comes with the Raspberry Pi 5
  • ELECROW Black Case for the Raspberry Pi 5, CrowPi is equipped with a 9-inch HD touchscreen along with a camera; All the regular components used in DIY electronics are packed into the CrowPi development board, such as LCD, LED matrix, buzzer, light sensor, PIR sensor, ultrasonic sensor, IR sensor, etc
  • Raspberry Pi Sensors: The Crowpi raspberry pi 5 programming kit is jam-packed with lots of buttons such as 19 different sensors in a tidy easy to use package; You don't have to wait and wire things
  • Build Quality: Solid ABS shell and well made components in one place make it strong and convenient to travel
  • Programming Lessons: This raspberry pi 5 learning kit ships with step by step instructions and provides 21 lessons to take you through identifying components reading code and running it in the terminal
architecture: lambda.Architecture.X86_64

Architecture must match across the function, layer, and native binaries. Changing only the function setting while retaining an incompatible layer does not fix the deployment.

Test locally without assuming the Lambda binary works headfully

The serverless Chromium build is intended for a headless Lambda environment. For local development, use a locally installed Chrome or Chromium, or a browser managed by Puppeteer, and select that executable in an IS_LOCAL branch.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const isLocal = process.env.IS_LOCAL === 'true';
const executablePath = isLocal
  ? process.env.LOCAL_CHROME_PATH
  : await chromium.executablePath();

const browser = await puppeteer.launch({
  args: isLocal ? [] : chromium.args,
  defaultViewport: chromium.defaultViewport,
  executablePath,
  headless: isLocal ? false : chromium.headless,
});

This separation prevents a headful local failure from being mistaken for a CDK packaging failure. Set LOCAL_CHROME_PATH to a browser executable that exists on the development machine, and test the deployed path separately in Lambda.

Deployment checklist

  1. Run npm ls @sparticuz/chromium and record the single version used at runtime.
  2. Read that release’s API table and declarations to determine whether executablePath is a getter or a function.
  3. Use exactly one call form: await chromium.executablePath for the getter API or await chromium.executablePath() for the function API.
  4. Choose bundle or layer packaging; do not leave an accidental second copy in the other location.
  5. If using a layer, verify nodejs/node_modules/@sparticuz/chromium in the archive and confirm the layer is attached.
  6. Set externalModules only for a module genuinely supplied by that layer.
  7. Keep the runtime package in dependencies, not only in devDependencies.
  8. Deploy x86_64 for releases that do not support ARM.
  9. In a non-production diagnostic deployment, log typeof chromium.executablePath and the resolved path once.
  10. Launch Puppeteer with chromium.args, chromium.defaultViewport, the resolved path, and the package’s headless setting.

Troubleshooting common Lambda failures

chromium.executablePath is not a function

Cause: The deployed release exposes a getter, or the runtime loaded an older duplicate. Fix: inspect the lockfile, bundle, and layer; then remove parentheses or update all copies to a function-style release.

/var/task/bin or an input-directory error

Cause: The package was bundled or externalized contrary to your chosen model, or the Chromium assets are absent from the expected directory. Fix: for a layer, verify the nodejs layout and externalize the module; for a bundled function, stop externalizing it and rebuild the asset. If your layer stores extracted files elsewhere, pass the supported location to executablePath(location).

Rank #4
CanaKit Raspberry Pi 5 Desktop PC with SSD (Fully Assembled) (256 GB SSD)
  • Fully assembled for plug-and-play operation
  • Includes Raspberry Pi 5 with 8GB RAM
  • 256 GB PCIe Pi NVMe SSD (Pre-loaded with Pi 64-Bit OS)
  • M.2 HAT+
  • CanaKit Turbine Black Case for the Pi 5

Execution-format or ELF errors on startup

Cause: An ARM64 function is executing a binary built for x86_64. Fix: deploy the function and matching layer as Architecture.X86_64, or select a package release that explicitly supports your architecture.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Cannot find module '@sparticuz/chromium'

Cause: The dependency was omitted from production installation, was marked external without a layer, or the layer path is wrong. Fix: move it to dependencies, remove inappropriate externalization, or correct the layer archive and attachment.

Local code works but Lambda still throws the old error

Cause: CDK or CI deployed a cached asset, a stale layer version, or a second package copy. Fix: inspect the deployed artifact rather than only source files, invalidate the stale asset, publish the intended layer version, and redeploy.

The path resolves but Puppeteer cannot launch

Cause: The executable path is valid but the binary’s architecture, extraction directory, launch arguments, or Lambda packaging is wrong. Fix: confirm x86_64 compatibility, use chromium.args, ensure the extraction directory is writable and present, and test with the headless settings intended for Lambda.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup:

If your goal is simply to obtain a clean website image or PDF rather than maintain Chromium in CDK, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
RasTech Raspberry Pi 5 8GB Kit with Active Cooler and Pi5 Case
  • 【What you Get】You will get 1*Pi 5 8GB Single Board,1*RasTech Case,1*Active Cooler,1*Screwdriver,1*Installation instructions,12-month free warranty, lifetime service, 24-hour prompt and friendly response.
  • 【More Connectors】There are two USB 3.0 ports(5Gbps simultaneously) and two USB 2.0 ports, which triple total bandwidth ,support any combination of up to two cameras or displays. Peak SD card performance is doubled through support for the SDR104 high-speed mode. It provides a smooth desktop experience for you. Offer Gigabit Ethernet and a PCIe interface, along with dual-band Wi-Fi and Bluetooth 5.0/BLE wireless capability. The RasTech Pi 5 Kit use the new 27W 5.1V 5A USB-C power connector.
  • 【 Support Dual 4Kp60 Display 】Each of the two microHDMI sockets can control a 4K display at 60 Hertz, now support HDR, offering super HD video for media streaming projects. RPi 5 is the first RPi model that comes with a PCI Express port (PCIe 2.0 x1 with 500 MB/s) to attach SSDs (requires separate M.2 HAT).
  • 【 Excellent Chips And Applications】Pi 5 is a full-size Pi computer using silicon built in-house at Pi. The RP1 “southbridge” provides the bulk of the I/O capabilities for Pi 5. Pi 5 is more friendly and convenient in the development of Internet of Things, Web development, machine identification, automatic control and other electronic equipment applications and network.
  • 【 Faster CPU, Better GPU 】 Pi 5 features a Broadcom BCM2712 64-bit quad-core Arm Cortex-A76 processor running at 2.4GHz, it delivers a 2–3× increase in CPU performance relative to RaspberryPi 4. The 800MHz VideoCore VII GPU is compatible to OpenGL ES 3.1 and Vulkan 1.2, substantial uplift in graphics performance. Pi 5 Offers lightning-fast CPU speed, a PCI Express interface, a Real Time Clock (RTC) and a power button and runs significantly cooler than Pi 4.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 screenshots per month with no card, and paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to get started.

FAQ

Can I support both getter and function releases in one codebase?

Yes, but an explicit package upgrade is clearer and safer. If you must run against multiple releases, inspect typeof chromium.executablePath and handle the two shapes deliberately, then standardize the dependency in deployment so production is deterministic.

Does changing the Puppeteer version fix this TypeError?

Not directly. The mismatch is in the @sparticuz/chromium export shape. Puppeteer still needs a valid resolved executable path, but changing Puppeteer alone does not turn a getter into a function.

Should every Lambda function get its own Chromium layer?

No. A compatible layer can be shared by multiple functions, provided each function attaches the layer and uses a package API compatible with its contents. Separate layers can be simpler when functions must move versions independently.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I support both getter and function releases in one codebase?

Yes, but standardizing one @sparticuz/chromium release for deployment is safer. If compatibility is unavoidable, inspect the runtime type before resolving the path.

Does changing Puppeteer fix this TypeError?

No. The error comes from the @sparticuz/chromium export shape; Puppeteer only consumes the resolved executable path.

Can one Chromium layer serve multiple Lambda functions?

Yes, when the layer is compatible with every attached function and each function is configured to load the layer-supplied module.

Quick Recap

Bestseller No. 1
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM); CanaKit Turbine Black Case for the Raspberry Pi 5
$259.95
Bestseller No. 2
CanaKit Raspberry Pi 4 4GB Starter PRO Kit - 4GB RAM
CanaKit Raspberry Pi 4 4GB Starter PRO Kit - 4GB RAM
Includes Raspberry Pi 4 4GB Model B with 1.5GHz 64-bit quad-core CPU (4GB RAM); Includes Pre-Loaded 32GB EVO+ Micro SD Card (Class 10), USB MicroSD Card Reader
$159.99
Bestseller No. 4
CanaKit Raspberry Pi 5 Desktop PC with SSD (Fully Assembled) (256 GB SSD)
CanaKit Raspberry Pi 5 Desktop PC with SSD (Fully Assembled) (256 GB SSD)
Fully assembled for plug-and-play operation; Includes Raspberry Pi 5 with 8GB RAM; 256 GB PCIe Pi NVMe SSD (Pre-loaded with Pi 64-Bit OS)
$339.97

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.