{"record":{"id":"02b7d03920f0b8d0","repo":"FlowiseAI/Flowise","slug":"file-filename-not-found-02b7d0","errorCode":null,"errorMessage":"File ${fileName} not found","messagePattern":"File (.+?) not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/src/storage/S3StorageProvider.ts","lineNumber":328,"sourceCode":"\n                    // Delete the old file\n                    await this.s3Client.send(\n                        new DeleteObjectsCommand({\n                            Bucket: this.bucket,\n                            Delete: {\n                                Objects: [{ Key: fallbackKey }],\n                                Quiet: false\n                            }\n                        })\n                    )\n\n                    // Check if the directory is empty and delete recursively if needed\n                    await this.cleanEmptyS3Folders(chatflowId)\n\n                    return fileContent\n                }\n            } catch (fallbackError) {\n                throw new Error(`File ${fileName} not found`)\n            }\n        }\n    }\n\n    async getFilesListFromStorage(...paths: string[]): Promise<FileInfo[]> {\n        let Key = paths.reduce((acc, cur) => acc + '/' + cur, '')\n        if (Key.startsWith('/')) {\n            Key = Key.substring(1)\n        }\n\n        const listCommand = new ListObjectsV2Command({\n            Bucket: this.bucket,\n            Prefix: Key\n        })\n        const list = await this.s3Client.send(listCommand)\n\n        if (list.Contents && list.Contents.length > 0) {\n            return list.Contents.map((item) => ({","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/src/storage/S3StorageProvider.ts#L310-L346","documentation":"Re-thrown inside the catch block of the S3 file-read fallback path. After the primary key is not found, the provider attempts a legacy key layout (without orgId); if that fallback GetObject also fails, the error is replaced with an explicit not-found message naming the fileName.","triggerScenarios":"Requesting a file whose object does not exist under either the orgId-scoped key or the legacy key layout. The throw is at S3StorageProvider.ts:327 inside `catch (fallbackError)`.","commonSituations":"The object was deleted or never uploaded; orgId migration moved it to a different key; eventual-consistency delay after a delete/upload.","solutions":["Confirm the object exists in the bucket under both candidate key layouts.","Return 404 to the client, exposing only the fileName.","Re-upload or restore the object if it was deleted."],"exampleFix":"// before\nconst data = await provider.streamStorageFile(chatflowId, chatId, fileName, orgId)\n// after\ntry {\n  const data = await provider.streamStorageFile(chatflowId, chatId, fileName, orgId)\n} catch (e) {\n  if (/not found/i.test(e.message)) return res.status(404).send('file not found')\n  throw e\n}","handlingStrategy":"try-catch","validationCode":"async function s3ObjectExists(client: S3Client, bucket: string, key: string): Promise<boolean> {\n  try {\n    await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }))\n    return true\n  } catch { return false }\n}\n// TOCTOU possible; pair with try-catch","typeGuard":"function isS3NotFound(err: unknown): boolean {\n  return err instanceof Error && /not found/i.test(err.message)\n}","tryCatchPattern":"try {\n  const data = await provider.streamStorageFile(chatflowId, chatId, fileName, orgId)\n} catch (e) {\n  if (e instanceof Error && /not found/i.test(e.message)) return res.status(404).send('file not found')\n  throw e\n}","preventionTips":["Map S3 not-found to 404 at the controller.","Confirm the key layout before serving.","Do not retry a confirmed-missing object."],"tags":["aws","s3","storage","file-not-found"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}