Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lambda layer artifact: no such file or directory since version 2.12 #270

Open
nancyatdoshii opened this issue Apr 5, 2022 · 11 comments
Open

Comments

@nancyatdoshii
Copy link

Hi, we 've been having this error message since the 2.12 update
ENOENT: no such file or directory, open 'project/.serverless/LambdaNodeModules.zip

Our Lambda layer config is as below

layers:
  LambdaNodeModules:
    description: Dependencies for project
    package:
      artifact: LambdaNodeModules.zip
    compatibleArchitectures:
      - x86_64
    compatibleRuntimes:
      - nodejs14.x

We are using serverless 2.72.3

@medikoo
Copy link
Contributor

medikoo commented Apr 5, 2022

@mmeyers-xomly do you know why it would be the case?

@jebricker
Copy link

Have you tried just using the arn of the layer? That is what I use in my serverless.yml and have not had an issue.

@Airaken
Copy link

Airaken commented Aug 27, 2022

It seems that the plugin is not recognizing the layers, so it does not add them in the .build and when deploying it does not find the files and that is when the error occurs

@NoxHarmonium
Copy link

I'm having the same issue which is fixed after I downgrade to 2.1.1

In my case the layer is built by an external plugin, then the layer zip file is referenced directly like the original poster. This config works with all the other bundlers I've tried so I think it is definitely an serverless-plugin-typescript issue introduced in 2.1.2

I suspect it might be this line:

https://github.com/mmeyers-xomly/serverless-plugin-typescript/blob/d8032babc29905c778805033333c0ce2da5841a2/src/index.ts#L255

I'd say that we should only overwrite artifact if it hasn't already been set by something else explicitly.

Something like this:

if (service.layers[name].package.artifact === undefined) {
   service.layers[name].package.artifact = path.join(
        this.originalServicePath,
        SERVERLESS_FOLDER,
        path.basename(service.layers[name].package.artifact)
      )
}

What do you think?

@NoxHarmonium
Copy link

After playing around with this for a bit, I have realised that the breaking change actually transforms the existing value of "service.layers[name].package.artifact" so my suggestion won't work. I'll have to keep looking in to it.

@NoxHarmonium
Copy link

I think we need to break the assumption that every layer has been moved by serverless-plugin-typescript and only reset the reference if the artifact was originally from the source folder.

Something like this might work better. I still need to give it a good test.

---
 src/index.ts | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/index.ts b/src/index.ts
index b610004..1b4eb3d 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -254,18 +254,32 @@ export class TypeScriptPlugin {
   async moveArtifacts(): Promise<void> {
     const { service } = this.serverless
 
+    const sourcePath = path.join(this.originalServicePath, BUILD_FOLDER, SERVERLESS_FOLDER)
+    const destinationPath = path.join(this.originalServicePath, SERVERLESS_FOLDER)
+
     await fs.copy(
-      path.join(this.originalServicePath, BUILD_FOLDER, SERVERLESS_FOLDER),
-      path.join(this.originalServicePath, SERVERLESS_FOLDER)
+      sourcePath,
+      destinationPath
     )
 
+    // After this function returns, the build folder will be deleted
+    // because the files have been copied into the .serverless folder.
+    // However, serverless will still be looking for that build folder
+    // at deploy time because it doesn't know that it has been deleted.
+    // This updates the reference.
     const layerNames = service.getAllLayers()
     layerNames.forEach(name => {
-      service.layers[name].package.artifact = path.join(
-        this.originalServicePath,
-        SERVERLESS_FOLDER,
-        path.basename(service.layers[name].package.artifact)
-      )
+      const existingArtifactPath = service.layers[name].package.artifact;
+      // Only reset this reference if the artifact was originally copied by
+      // this plugin. Otherwise, leave it alone, because the user (or another plugin)
+      // has set this to a specific location.
+      if (path.dirname(existingArtifactPath) === sourcePath) {
+        service.layers[name].package.artifact = path.join(
+          this.originalServicePath,
+          SERVERLESS_FOLDER,
+          path.basename(existingArtifactPath)
+        )
+      }
     })
 
     if (this.options.function) {
-- 
2.37.3

@milindsingh
Copy link

Any update on this ?

@luccasmaso
Copy link

I can also confirm that downgrading to 2.1.1 fixes the issue

@sehrish30
Copy link

Facing the same issue however, it works when I deploy the whole service using sls deploy but single function deployment does not work

@bernardodesousa
Copy link

I'm seeing this problem with Serverless 3.30.1. and plugin 2.1.5. Here's how the layer is configured:

layers:
  ffmpeg:
    package:
      artifact: layers/ffmpeg.zip
    name: ${self:custom.stacks.this}-ffmpeg
    description: FFMPEG binary
    compatibleRuntimes:
      - nodejs14.x
    licenseInfo: GPL v2+, for more info see https://github.com/FFmpeg/FFmpeg/blob/master/LICENSE.md
    retain: false

When I try to package with serverless package, I get the following error:

OperationalError: ENOENT: no such file or directory, open '<project-root>/.serverless/ffmpeg.zip'

This error only shows up when I add the plugin. Things work as expected without the plugin.

I confirm that the problem is introduced with 2.1.2.

For now, we'll downgrade to 2.1.1 and follow this thread.

@makeryoungjin
Copy link

I fixed issue using another plugin "serverless-plugin-esbuild'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants