vxcontrol/pentagi · error

FlowFiles.AlreadyExists

FlowFiles.AlreadyExists

Error message

flow file '%s' already exists

What it means

Before saving, UploadFlowFiles checks whether a flow file with the same name already exists for the flow (via the flowfiles service). If it does, the upload aborts with FlowFiles.AlreadyExists rather than silently overwriting the stored object.

Source

Thrown at backend/pkg/server/services/flow_files.go:237

			err = fmt.Errorf("uploaded files total size %d bytes exceeds the maximum allowed size of %d bytes",
				totalSize, flowfiles.MaxUploadTotalSize)
			logger.FromContext(c).WithError(err).WithField("flow_id", flowID).Error("uploaded files total size too large")
			response.Error(c, response.ErrFlowFilesInvalidRequest, err)
			return
		}

		dstPath := filepath.Join(uploadDir, fileName)
		exists, err := flowfiles.LocalEntryExists(dstPath)
		if err != nil {
			logger.FromContext(c).WithError(err).WithFields(map[string]any{
				"flow_id":   flowID,
				"file_name": fileName,
			}).Error("error checking existing uploaded file")
			response.Error(c, response.ErrInternal, err)
			return
		}
		if exists {
			err = fmt.Errorf("flow file '%s' already exists", fileName)
			logger.FromContext(c).WithError(err).WithFields(map[string]any{
				"flow_id":   flowID,
				"file_name": fileName,
			}).Error("uploaded file already exists")
			response.Error(c, response.ErrFlowFilesAlreadyExists, err)
			return
		}

		pending = append(pending, pendingUpload{fileName: fileName, dstPath: dstPath})
	}

	// All files passed validation — write temporary files first to avoid partial commits on copy errors.
	for i := range pending {
		tmpPath, err := flowfiles.SaveUploadedFileToTemp(fileHeaders[i], uploadDir)
		if err != nil {
			logger.FromContext(c).WithError(err).WithFields(map[string]any{
				"flow_id":   flowID,
				"file_name": pending[i].fileName,

View on GitHub (pinned to ea665308ba)

Solutions

  1. Rename the file before upload so the name is unique within the flow (e.g. add a timestamp).
  2. Delete the existing flow file first (DeleteFlowFile) and retry the upload.
  3. Make the producer include a run-id/nonce in generated file names to guarantee uniqueness.
  4. Handle the AlreadyExists response in the client to prompt the user for overwrite/rename.

Example fix

// before
await uploadFlowFile(flowID, new File(blob, 'report.txt'));
// after
await uploadFlowFile(flowID, new File(blob, `report-${Date.now()}.txt`));
Defensive patterns

Strategy: try-catch

Validate before calling

const existing = await listFlowFiles(flowID);
const clash = existing.some(f => f.name === newName);
if (clash) newName = uniquifyName(newName);

Try / catch

try { await uploadFlowFile(flowID, file); } catch (e) { if (isAlreadyExists(e)) { await deleteFlowFile(flowID, file.name); await uploadFlowFile(flowID, file); } else throw e; }

Prevention

When it happens

Trigger: POSTing an upload whose file name matches an existing file in the same flow's data directory — e.g. re-running a job that produces 'report.txt' or 'nmap-output.xml'.

Common situations: Re-running a scan that regenerates identically-named output files; retrying a partially-failed upload; two clients uploading concurrently with default names.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/c246a5c0f24f96aa. Report an issue: GitHub.