Compare commits

...
Author SHA1 Message Date
Sonarly Claude Code 90e8b0e13b fix: handle missing package.json in copyDependenciesInMemory for S3 storage
https://sonarly.com/issue/24354?type=bug

Logic functions fail to execute when using S3 storage with LOGIC_FUNCTION_TYPE=LOCAL because `copyDependenciesInMemory` unconditionally tries to download `package.json` from S3 without checking if it exists first, throwing FILE_NOT_FOUND.

Fix: Added a `checkFileExists` guard for `package.json` in `copyDependenciesInMemory`, matching the existing pattern already used for `yarn.lock` in the same method.

**Before:** `package.json` was unconditionally downloaded from S3 storage. If the file didn't exist (e.g., workspace created before v1.17 backfill, or failed upload during workspace creation), the S3 driver threw `FileStorageException: File not found`, crashing logic function execution.

**After:** Both `package.json` and `yarn.lock` existence checks are parallelized via `Promise.all`. If `package.json` doesn't exist in storage, a minimal default is written locally (matching the pattern already used for missing `yarn.lock`). This allows logic function execution to proceed gracefully.

The fix is intentionally minimal — it only changes the internal resilience of `copyDependenciesInMemory` without modifying the method signature, so the two callers (`local.driver.ts` and `lambda.driver.ts`) require no changes.
2026-04-12 23:55:49 +00:00
@@ -257,24 +257,50 @@ export class LogicFunctionResourceService {
workspaceId: string;
inMemoryFolderPath: string;
}) {
const yarnLockExists = await this.fileStorageService.checkFileExists({
workspaceId,
applicationUniversalIdentifier,
fileFolder: FileFolder.Dependencies,
resourcePath: 'yarn.lock',
});
const promises = [];
promises.push(
this.fileStorageService.downloadFile({
const [packageJsonExists, yarnLockExists] = await Promise.all([
this.fileStorageService.checkFileExists({
workspaceId,
applicationUniversalIdentifier,
fileFolder: FileFolder.Dependencies,
resourcePath: 'package.json',
localPath: join(inMemoryFolderPath, 'package.json'),
}),
);
this.fileStorageService.checkFileExists({
workspaceId,
applicationUniversalIdentifier,
fileFolder: FileFolder.Dependencies,
resourcePath: 'yarn.lock',
}),
]);
const promises = [];
if (packageJsonExists) {
promises.push(
this.fileStorageService.downloadFile({
workspaceId,
applicationUniversalIdentifier,
fileFolder: FileFolder.Dependencies,
resourcePath: 'package.json',
localPath: join(inMemoryFolderPath, 'package.json'),
}),
);
} else {
const packageJsonPath = join(inMemoryFolderPath, 'package.json');
promises.push(
fs.mkdir(dirname(packageJsonPath), { recursive: true }).then(() =>
fs.writeFile(
packageJsonPath,
JSON.stringify({
name: 'logic-function-dependencies',
version: '1.0.0',
dependencies: {},
}),
'utf-8',
),
),
);
}
if (yarnLockExists) {
promises.push(