aws / aws/aws-sam-cli

NODE_OPTIONS is overwritten when invoking Lambdas with debugger

Open
#3,307 4 comments 4 reactions 0 assignees View on GitHub
area/local/invoke maintainer/need-followup type/bug
Dominant language
Python
Stars
6.7k
Forks
1.2k
Avg merge
1d 10h
Merged PRs (30d)
52

Description

### Description:
If I run a Lambda locally using aws-sam (`sam local start-lambda --env-vars .env.json --debug-port 5858`), the `NODE_OPTIONS` that I define in the environment variables are not available. I'm trying to pass `--experimental-loader /var/task/https-loader.mjs` specifically, and it works when invoking the Lambda without debugging enabled, but when I invoke with a debugger, the value of `process.env.NODE_OPTIONS` is `--require "/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/ms-vscode.js-debug/src/bootloader.bundle.js"` (I'm using the debugger in VS Code). I tried adding `"env": { "NODE_OPTIONS": "--experimental-loader /var/task/https-loader.mjs" }` to the VS Code debugger configuration, and the value of `process.env.NODE_OPTIONS` is `--require "/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/ms-vscode.js-debug/src/bootloader.bundle.js" --experimental-loader /var/task/https-loader.mjs`, but the experimental loader feature is not enabled.

I suspect that it's because the user's `NODE_OPTIONS` are being passed through to the `node` executable: https://github.com/aws/aws-sam-cli/blob/59f2d194b65360d5bdeb0b930ff4f8e6dbc7c809/samcli/local/docker/lambda_debug_settings.py#L141

### Steps to reproduce:

template.yml

```yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
hammies-api

Resources:
MyFunction
Type: AWS::Serverless::Function
Properties:
CodeUri: functions
Handler: index.handler
Runtime: nodejs14.x
Environment:
Variables:
NODE_OPTIONS: --experimental-loader /var/task/https-loader.mjs
```

functions.https-loader.mjs

```js
import { get } from 'https'

export function resolve(specifier, context, defaultResolve) {
const { parentURL = null } = context

// Normally Node.js would error on specifiers starting with 'https://', so
// this hook intercepts them and converts them into absolute URLs to be
// passed along to the later hooks below.
if (specifier.startsWith('https://')) {
return {
url: specifier,
}
} else if (parentURL && parentURL.startsWith('https://')) {
return {
url: new URL(specifier, parentURL).href,
}
}

// Let Node.js handle all other specifiers.
return defaultResolve(specifier, context, defaultResolve)
}

export function getFormat(url, context, defaultGetFormat) {
// This loader assumes all network-provided JavaScript is ES module code.
if (url.startsWith('https://')) {
return {
format: 'module',
}
}

// Let Node.js handle all other URLs.
return defaultGetFormat(url, context, defaultGetFormat)
}

export function getSource(url, context, defaultGetSource) {
// For JavaScript to be loaded over the network, we need to fetch and
// return it.
if (url.startsWith('https://')) {
return new Promise((resolve, reject) => {
get(url, (res) => {
let data = ''
res.on('data', (chunk) => (data += chunk))
res.on('end', () => {
// Transform source code
const source = data
.replace(
/main.variable\(observer\("(\w+)"\)\)\.define\("\w+", \[(.+)\], function\((.+)\)/g,
`main.variable(observer("$1")).define("$1", [$2,"fetch"], function($3,fetch)`
)
.replace(/main\.import\("spreadsheet", child\d\);\n/g, '')
.replace(/btoa\((.+)\)/g, `Buffer.from($1).toString('base64')`)
resolve({ source })
})
}).on('error', (err) => reject(err))
})
}

// Let Node.js handle all other URLs.
return defaultGetSource(url, context, defaultGetSource)
}
```

functions/index.js

```js
exports.handler = async (event) => {
try {
return 'success'
} catch (error) {
throw error
}
}
```

### Observed result:

```
ERROR Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only file and data URLs are s} code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'Runtime.js:66:25) {73:17)15:27)e.js:791:11)
```

### Expected result:

```
INFO success
```

### Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

1. OS: macOS 11.6
2. `sam --version`: 1.30.0
3. AWS region: us-east-1

`Add --debug flag to command you are running`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.