serverless: Serverless null error when using SSM variables that not exist in region

This is a Bug Report

Description

Serverless throws an error when using SSM variables that not exist in the AWS region.

For bug reports:

  • What went wrong? When the variable doesn’t exists in the configured region, I get a null error in serverless
$ /Users/chris/prj/fb/lambda-service/node_modules/.bin/sls package --environment development

  Serverless Error ---------------------------------------


  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com

  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           8.10.0
     Serverless Version:     1.28.0

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
  • What did you expect should have happened? sls script runs normally

  • What was the config you used?

service: service
provider:
  name: aws
  runtime: nodejs8.10
  region: ${file(./config/${opt:environment}.json):aws.region}
  stage: ${opt:environment}
  profile: myprofile
  memorySize: 128
  timeout: 30
  environment:
    MY_VARIABLE: ${ssm:/myvariable, '${file(./config/${opt:environment}.json):myvariable}'}
  • What stacktrace or error message from your provider did you see? I got this after adding a console log in getValueFromSsm, seems that the promise is rejected because something changed in the error message expected in this case
      .catch((err) => {
        // console.log(err);
        const expectedErrorMessage = `Parameter ${param} not found.`;
        if (err.message !== expectedErrorMessage) {
          return BbPromise.reject(new this.serverless.classes.Error(err.message));
        }
        return BbPromise.resolve(undefined);
      });
{ ServerlessError: Parameter /myvariable not found.
    at BbPromise.fromCallback.catch.err (/Users/chris/prj/fb/lambda-service/node_modules/serverless/lib/plugins/aws/provider/awsProvider.js:270:11)
    at tryCatcher (/Users/chris/prj/fb/lambda-service/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Users/chris/prj/fb/lambda-service/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/Users/chris/prj/fb/lambda-service/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/Users/chris/prj/fb/lambda-service/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/Users/chris/prj/fb/lambda-service/node_modules/bluebird/js/release/promise.js:689:18)
    at Async._drainQueue (/Users/chris/prj/fb/lambda-service/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/Users/chris/prj/fb/lambda-service/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/Users/chris/prj/fb/lambda-service/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:794:20)
    at tryOnImmediate (timers.js:752:5)
    at processImmediate [as _immediateCallback] (timers.js:729:5)
  name: 'ServerlessError',
  statusCode: 400,
  providerError:
   { ParameterNotFound: Parameter /myvariable not found.
    at Request.extractError (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/protocol/json.js:48:27)
    at Request.callListeners (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
    at Request.emit (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
    at Request.emit (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
    at callNextListener (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:95:12)
    at IncomingMessage.onEnd (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/event_listeners.js:269:13)
    at emitNone (events.js:111:20)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
     cause:
      { ParameterNotFound: Parameter /myvariable not found.
    at Request.extractError (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/protocol/json.js:48:27)
    at Request.callListeners (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
    at Request.emit (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
    at Request.emit (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
    at callNextListener (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/sequential_executor.js:95:12)
    at IncomingMessage.onEnd (/Users/chris/prj/fb/lambda-service/node_modules/serverless/node_modules/aws-sdk/lib/event_listeners.js:269:13)
    at emitNone (events.js:111:20)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
        message: 'Parameter /myvariable not found.',
        code: 'ParameterNotFound',
        time: 2018-07-10T12:56:54.931Z,
        requestId: 'cda55b82-7fa9-4cdc-8b99-6e27a06f3eb0',
        statusCode: 400,
        retryable: false,
        retryDelay: 44.30403493043325 },
     isOperational: true,
     code: 'ParameterNotFound',
     time: 2018-07-10T12:56:54.931Z,
     requestId: 'cda55b82-7fa9-4cdc-8b99-6e27a06f3eb0',
     statusCode: 400,
     retryable: false,
     retryDelay: 44.30403493043325 } }

Additional Data

  • Serverless Framework Version you’re using: 1.28.0
  • Operating System: macos
  • Stack Trace: added above
  • Provider Error messages: ParameterNotFound

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 19
  • Comments: 18 (8 by maintainers)

Commits related to this issue

Most upvoted comments

PR is now passing. The tests were sending a 123 error code instead of a 400.

Encountering this issue both with serverless-offline and deploying. It seems to occur any time Serverless encounters an SSM parameter that does not exist, even if there is a default to fallback to. Temporarily worked around this issue by commenting out

        const expectedErrorMessage = `Parameter ${param} not found.`;
        if (err.message !== expectedErrorMessage) {
          return BbPromise.reject(new this.serverless.classes.Error(err.message));
        }

in classes/Variables.js:695. Perhaps the exact shape of AWS’s error message has changed?

Additional note: Affects all versions from 1.26 through 1.28

You can do this:

        const errorCode = _.get(err, 'providerError.cause.code');
        const expectedCode = 'ParameterNotFound';
        if (errorCode !== expectedCode) {
          return BbPromise.reject(new this.serverless.classes.Error(err.message));
        }
        return BbPromise.resolve(undefined);

@gcphost yep, I thought the same after checking the latest releases, seems that AWS changed something since the project was working the before.

Can also confirm that err.message is null. I’m also seeing that the error message is missing in the AWS CLI and python’s boto3, so it seems like AWS removed the error message entirely from that SSM endpoint.

Upon further inspection of the error that’s being raised in the JS, it seems like there’s a lot of other information contained in that error object that could be used to determine if the error is in fact a ParameterNotFound error. It’s not clear why the choice was made to do a string comparison on the message itself over, say, checking the HTTP status code, but that would probably to allow “missing param” errors to pass through as a warning.

I decided to check this AM and simply put, err.message is null.

expectedErrorMessage is only used once and is a waste to define as a const so I did this:

        if (err.message && err.message !== `Parameter ${param} not found.`) {
          return BbPromise.reject(new this.serverless.classes.Error(err.message));
        }
        return BbPromise.resolve(undefined);

I’m uncertain if the error message will ever equal Parameter ${param} not found. again, but in case it does I have left it.