Skip to content

Clean up partial remote package artifact downloads on failure #220

@GrahamCampbell

Description

@GrahamCampbell

Summary

Remote S3 package artifact downloads can leave a partially written temp file behind when the download stream or destination write stream fails.

This is pre-existing robustness debt, not a regression from the AWS SDK v3 S3 data-plane migration. The previous SDK v2 implementation streamed S3.getObject(...).createReadStream() into fs.createWriteStream(filePath) and rejected on stream errors without deleting filePath. The SDK v3 implementation now uses stream/promises.pipeline(response.Body, fs.createWriteStream(filePath)), which improves error propagation but preserves the same partial-file cleanup behavior.

Impact

  • Failed remote artifact downloads can leave partial files in the framework temp directory.
  • The service/package artifact path is preserved on failure, so this should not affect deployment correctness.
  • This is robustness/cleanup behavior, not currently known to be a security issue.

Suggested Fix

In lib/plugins/aws/package/compile/functions.js, wrap only the streamed download write in cleanup logic:

try {
  await pipeline(response.Body, fs.createWriteStream(filePath));
} catch (error) {
  try {
    await fsp.unlink(filePath);
  } catch (unlinkError) {
    if (unlinkError.code !== 'ENOENT') {
      // Do not mask the original download failure.
    }
  }
  throw error;
}

The exact implementation should avoid masking the original download/write error if cleanup fails.

Test Coverage

Add coverage under test/unit/lib/plugins/aws/package/compile/functions.test.js for:

  • read stream failure rejects with the original error
  • write stream failure rejects with the original error
  • function/service artifact path remains unchanged on failure
  • partial temp file is removed after failure
  • cleanup ENOENT is ignored
  • cleanup failure does not mask the original download/write error

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions