serverless
serverless copied to clipboard
AWS API Gateway: Error when renaming path variable
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
pathvartopathVar. - 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.
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.
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?
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
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
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
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?
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+}.
- serverless.yml (initial state):
path: /{one}/{two}/{proxy+} - serverless.yml:
path: / sls deploysls deployagain not sure if this was necessary..curl http://<api>/was now working butcurl http://<api>/arg1/arg2/the/restwas 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?- serverless.yml (final state):
path: /{one}/{two}/{three}/{proxy+} sls deploysls deployagain not sure if this was necessary butcurl http://<api>/arg1/arg2/arg3/the/restwas now working butcurl 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.
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....
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.
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.
Is any solution available?
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 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.
@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}
@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
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
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
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.
FWIW, I just ran into this today. Very frustrating to have to take the function down.
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.
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...
Confirm that we are also seeing this error.
Same thing here...
Still seeing this issue
Getting this issue.
I suspect a workaround/fix for this is tricky in that it smells more like a cloudformation issue than a serverless one...
still a thing
Still experiencing this issue
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}"