vxcontrol/pentagi · error

FlowFiles.NotFound

FlowFiles.NotFound

Error message

no accessible paths found

What it means

DownloadFlowFile resolves each requested path (inside the flow's working directory / container volume) and stats it; only entries that exist and are accessible are collected. If every requested path failed resolution — nonexistent, permission-denied, or filtered — the handler returns FlowFiles.NotFound ('no accessible paths found') instead of a partial download.

Source

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

				logger.FromContext(c).WithError(err).WithField("flow_id", flowID).Error("error reading cached flow file")
				response.Error(c, response.ErrInternal, err)
			}
			return
		}
		// Never serve symlinks — could point outside the flow data directory.
		if info.Mode()&os.ModeSymlink != 0 {
			response.Error(c, response.ErrFlowFilesNotFound, fmt.Errorf("'%s' not found in local cache", reqPath))
			return
		}
		if !info.IsDir() && !info.Mode().IsRegular() {
			response.Error(c, response.ErrFlowFilesNotFound, fmt.Errorf("'%s' not found in local cache", reqPath))
			return
		}
		entries = append(entries, resolvedEntry{reqPath: reqPath, localPath: localPath, info: info})
	}

	if len(entries) == 0 {
		response.Error(c, response.ErrFlowFilesNotFound, errors.New("no accessible paths found"))
		return
	}

	// Single regular file → serve as a direct attachment.
	// We open the file explicitly and use DataFromReader with a known Content-Length
	// so that Gin's response writer emits a proper Content-Length header instead of
	// relying on http.ServeFile, which conflicts with Gin's middleware-set headers
	// and can produce content-length: 0 in certain request contexts.
	if len(entries) == 1 && entries[0].info.Mode().IsRegular() {
		e := entries[0]
		f, err := os.Open(e.localPath)
		if err != nil {
			logger.FromContext(c).WithError(err).WithField("flow_id", flowID).Error("error opening flow file for download")
			response.Error(c, response.ErrInternal, err)
			return
		}
		defer f.Close()

View on GitHub (pinned to ea665308ba)

Solutions

  1. List available files first (GET /flows/<id>/files) and download an exact returned path
  2. Use a flow-relative path rather than a host or container absolute path
  3. Verify the file still exists and the flow/container is still running
  4. Check for typos and case sensitivity in the path

Example fix

// before
GET /api/v1/flows/42/files/download?path=/root/report.txt
// after
GET /api/v1/flows/42/files/download?path=report.txt  (flow-relative, confirmed via list endpoint)
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check existence via the list endpoint
const listed = await api.get(`/flows/${flowId}/files`);
const available = new Set(listed.data.files.map(f => f.path));
const valid = paths.filter(p => available.has(p));
if (valid.length === 0) throw new Error('none of the requested paths exist for this flow');

Try / catch

try {
  const res = await api.get(`/flows/${flowId}/files/download`, { params, responseType: 'blob' });
} catch (e) {
  if (e.response?.status === 404) {
    // refresh the file listing and prompt the user to reselect
    await refreshFileList();
    notify('Requested files are no longer accessible');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /flows/{flow_id}/files/download?path=<p> where <p> (and all paths[] entries) do not resolve to an existing, readable file or directory — wrong relative path, file already deleted, or path outside the allowed root rejected during resolution.

Common situations: Downloading before the flow's container has produced the file; path typos or absolute vs relative path confusion; files removed between listing and download; case-sensitive path mismatches.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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