serverless icon indicating copy to clipboard operation
serverless copied to clipboard

AWS API Gateway: Error when renaming path variable

Open matheusvellone opened this issue 8 years ago • 84 comments

This is a Bug Report

Description

Tried to rename a path variable and got the error. Deployed a service with the following yml config:

service: aws-nodejs

provider:
    name: aws
    runtime: nodejs6.10

functions:
    hello:
        handler: handler.hello
        events:
            - http:
                path: /{pathvar}
                method: put

Then changed it to

service: aws-nodejs

provider:
    name: aws
    runtime: nodejs6.10

functions:
    hello:
        handler: handler.hello
        events:
            - http:
                path: /{pathVar} # Changed this variable
                method: put

Then tried to redeploy the service to update the variable name and got the error.

For bug reports:

  • What went wrong? An error occurred while provisioning your stack: ApiGatewayResourcePathvarVar. A sibling ({pathvar}) of this resource already has a variable path part -- only one is allowed.
  • What did you expect should have happened? Expected the service to deploy the new route over the old one. Renaming the path variable from pathvar to pathVar.
  • What stacktrace or error message from your provider did you see? An error occurred while provisioning your stack: ApiGatewayResourcePathvarVar - A sibling ({pathvar}) of this resource already has a variable path part -- only one is allowed

Similar or dependent issues:

  • #3075

Additional Data

  • Serverless Framework Version you're using: 1.15.3
  • Operating System: WIN 10
  • Provider Error messages: An error occurred while provisioning your stack: ApiGatewayResourcePathvarVar. A sibling ({pathvar}) of this resource already has a variable path part -- only one is allowed.

If more information is needed, just let me know.

matheusvellone avatar Jun 12 '17 18:06 matheusvellone

I have the same issue when removing variable from path.

Old yml config:

load:
    handler: handler.load
    events:
      - http:
          path: load/{key}/{account}/{id}
          method: get
          cors: true
          integration: lambda
          request:
            parameters:
              paths:
                id: true
                key: true
                account: true

Updated yml:

load:
    handler: handler.load
    events:
      - http:
          path: load/{key}/{id}
          method: get
          cors: true
          integration: lambda
          request:
            parameters:
              paths:
                id: true
                key: true

Error: An error occurred while provisioning your stack: ApiGatewayResourceLoadKeyVarIdVar - A sibling ({account}) of this resource already has a variable path part -- only one is allowed.

Tlapi avatar Jul 08 '17 11:07 Tlapi

It seems that CF first tries to add the new resource, and then to remove the old resource. This leads to an intermediate state where both resources will exist, which is of course not possible, because they interfere with each other.

Just some unordered thoughts to get a discussion running:

  • Using dependencies is no option, as the final stack should only contain the new path resource
  • Maybe creating an intermediate changeset (to remove the old resource) could be used before updating the stack. This would mean to add a local resource precheck and handling to Serverless that identifies if we run into this condition.
  • Is there any other way but dependencies to tell CF about the needed order?

HyperBrain avatar Jul 09 '17 12:07 HyperBrain

Workaround for now: Comment out the function from your serverless.yml, run a full deployment. This will delete the API gateway endpoint entirely, and then you can uncomment the function and run a deployment to deploy the new function with the new pathParam.

pettyalex avatar Oct 31 '17 14:10 pettyalex

@pettyalex thanks, It was quite a relief.
Someone know why serverless removes the older at last instead of doing it first, Is that because someone may be using the older versions at the deployment time of new one

deQuota avatar Feb 07 '18 13:02 deQuota

I'm using the workaround suggested by @pettyalex but unfortunately makes me hit another issue where cloudformation stalls in the state UPDATE_COMPLETE_CLEANUP_IN_PROGRESS where it is taking a long time to delete lambdas inside VPCs: https://forum.serverless.com/t/very-long-delay-when-doing-sls-remove-of-lambda-in-a-vpc/2535

kristianperkins avatar May 02 '18 05:05 kristianperkins

Thing is, deleting the API and then creating it again changes the URL endpoint. This is pretty destructive, is there a less destructive solution to this?

peterecofit avatar Jun 02 '18 22:06 peterecofit

Im new to serverless framework, but found workaround that worked for me and didnt result in a change to the endpoint hostname. It might still cause a short outage for your service because it seems the resource paths are not responding correctly, but that might be acceptable considering you are changing the paths. Its better than deleting the entire api endpoint tho.

This workaround changes the path from /{one}/{two}/{proxy+} to /{one}/{two}/{three}/{proxy+}.

  1. serverless.yml (initial state): path: /{one}/{two}/{proxy+}
  2. serverless.yml: path: /
  3. sls deploy
  4. sls deploy again not sure if this was necessary.. curl http://<api>/ was now working but curl http://<api>/arg1/arg2/the/rest was also still was working even tho I had removed it from serverless.yml. maybe i just needed to wait longer than a few minutes for an update?
  5. serverless.yml (final state): path: /{one}/{two}/{three}/{proxy+}
  6. sls deploy
  7. sls deploy again not sure if this was necessary but curl http://<api>/arg1/arg2/arg3/the/rest was now working but curl http://<api>/ was also still was working even tho I had removed it from serverless.yml. maybe i just needed to wait longer than a few minutes for an update?

It seems there is something very wrong with the CloudFormation updates to ApiGatewayResourcePathvarVar resources, but I could see the argument that this is not that big of an issue because changing path variables is not something that will be done in production very often. I think api developers would be better off adding new endpoints and deprecating old ones (tho maybe I am misunderstanding the workflow here, like I said Im new to this framework). I only ran into this issue making a simple example serverless app.

atheiman avatar Jun 06 '18 17:06 atheiman

So the accepted solution here requires you to take down the routes. Not really acceptable if you are just changing marginal things (e.g. making path parameter required) and the route are live in production and used heavily. Bleeding edge is bleeding edge....

simlu avatar Jul 05 '18 15:07 simlu

This can be a problem for when a route has been deleted, and a new route with a variable in the same part of the path is now being added. IE: some/{path} # some/{path} (removing the url from API gateway) some/{path2} (fails to deploy)

It looks to me that this has something to do with the way stage works, and the workaround is still to destroy the entire API gateway and rebuild.

MacMcIrish avatar Jul 05 '18 16:07 MacMcIrish

Any news on this issue? We have trouble as well and undeploying the entire api/path is not really acceptable since it runs live in production. Is canary maybe a solution to make it a more smooth transition?

update: Nevermind, it looks like its not a problem with Serverless, its in cloudformation. When you change your path in ApiGateway it creates the new resources and then directly starts the deployment. Including your old path/methods. After the deployment it starts the cleanup and removes your old resources.

FBloembergen avatar Oct 10 '18 08:10 FBloembergen

Is any solution available?

avi2021 avatar Jan 28 '19 12:01 avi2021

So the accepted solution here requires you to take down the routes. Not really acceptable if you are just changing marginal things (e.g. making path parameter required) and the route are live in production and used heavily. Bleeding edge is bleeding edge....

I agree, this should have way higher priority and should have been fixed a long time ago. This issue is close to being 2.5 years old and this bug can be a real showstopper for some applications.

laurensV avatar Sep 06 '19 13:09 laurensV

@laurensV We stopped using path parameter entirely and route and validate in application logic with a single resolver route (using lambda-serverless-api on npm, disclaimer I'm the author).

There are still problems with rouge routes in stage as @MacMcIrish described, but if you do a drift detection in cf after a deploy the next deploy seems to be removing the stage path.

Not ideal but at least we don't need to remove and redeploy anymore.

simlu avatar Sep 06 '19 14:09 simlu

@josephnaber no, cloudformation considers that a conflicting path. Please read the previous comments. As an aside, your paths should probably look like /notes/{noteid} /entities/{entityid}/notes/{noteid}

MacMcIrish avatar Sep 12 '19 17:09 MacMcIrish

@laurensV We stopped using path parameter entirely and route and validate in application logic with a single resolver route (using lambda-serverless-api on npm, disclaimer I'm the author).

There are still problems with rouge routes in stage as @MacMcIrish described, but if you do a drift detection in cf after a deploy the next deploy seems to be removing the stage path.

Not ideal but at least we don't need to remove and redeploy anymore.

Nice I will take a look at the package! Kinda goes against the idea of serverless where each function is deployed and scaled separately as you now use 1 lambda for your entire application, but these kind of bugs make it almost impossible to use serverless in a good way

laurensV avatar Sep 12 '19 19:09 laurensV

For me the issue was that the path parameters that are in the same place in the path should have the same names. E.g., if you have the paths /user/{userId} and the path /user/{accountId}/{userId} it throws this error. Changing the latter path to /user/{userId}/{accountId} fixes the error.

See this answer https://github.com/serverless/serverless/issues/1909#issuecomment-282899881

AnneAlbert avatar Dec 11 '19 14:12 AnneAlbert

For me the issue was that the path parameters that are in the same place in the path should have the same names. E.g., if you have the paths /user/{userId} and the path /user/{accountId}/{userId} it throws this error. Changing the latter path to /user/{userId}/{accountId} fixes the error.

See this answer #1909 (comment)

That is a different problem, as this bug also appears even when you only have one path and you try to rename one of the parameters

laurensV avatar Dec 11 '19 14:12 laurensV

That is a different problem, as this bug also appears even when you only have one path and you try to rename one of the parameters

Wouldn't it still be the same problem though? If you rename a parameter and then deploy, as stated above the deployment includes new and old paths, where the old paths are only cleaned up after the deployment. This means that at deployment time, you would have the paths /user/{oldParamName} and /user/{newParamName}, which is in fact the same as the scenario I described above.

Difference is that in my case it's not exactly a bug, but in the case of renaming path variables it is a bug stemming from the deployment workflow.

AnneAlbert avatar Dec 11 '19 15:12 AnneAlbert

FWIW, I just ran into this today. Very frustrating to have to take the function down.

jrkarnes avatar Jan 08 '20 21:01 jrkarnes

My team also ran into this. I'd like to see this fixed in the near future to at least be able to gracefully change or some kind of warning explaining what's what.

zomgbre avatar Feb 12 '20 12:02 zomgbre

Have been watching this issue for some time because I ran into it a while back. Ran into it again today. Not sure how this hasn't been fixed yet... it's been open a long time and the solutions offered are not viable for live production systems. Would love to see this addressed asap. Pretty please...

strepto42 avatar Feb 18 '20 23:02 strepto42

Confirm that we are also seeing this error.

terrygruenewald avatar Feb 28 '20 23:02 terrygruenewald

Same thing here...

serban-mihai avatar Mar 02 '20 12:03 serban-mihai

Still seeing this issue

mrowles avatar Apr 01 '20 03:04 mrowles

Getting this issue.

silverhero13 avatar Apr 03 '20 03:04 silverhero13

I suspect a workaround/fix for this is tricky in that it smells more like a cloudformation issue than a serverless one...

strepto42 avatar Apr 03 '20 03:04 strepto42

still a thing

lucasmarcelli avatar Apr 27 '20 15:04 lucasmarcelli

Still experiencing this issue

NathanBarnard avatar May 07 '20 03:05 NathanBarnard

It has been solved!

That's what I'm gonna say some magical day in the future, because right now it's still an issue 👎🏼

Confirmed, I still have this issue where we update the {proxy+} and keep the rest the same E.g: Change from "api/v1/user/{userName}" to "api/v1/user/{userID}"

ctrongminh avatar May 13 '20 00:05 ctrongminh