vxcontrol/pentagi · error

failed to resolve data directory: %w

Error message

failed to resolve data directory: %w

What it means

This error wraps filepath.Abs failing while resolving the configured data directory (fte.cfg.DataDir) to an absolute path for the flow's cached uploads directory. filepath.Abs only fails when it cannot determine the current working directory (os.Getwd error), e.g. the working directory was deleted. The wrapped error comes from os.Getwd.

Source

Thrown at backend/pkg/tools/tools.go:736

	return writeErr
}

func convertSyncEntriesToTarEntries(entries []fileSyncEntry) []flowfiles.TarEntry {
	tarEntries := make([]flowfiles.TarEntry, 0, len(entries))
	for _, entry := range entries {
		tarEntries = append(tarEntries, flowfiles.TarEntry{
			LocalPath: entry.localPath,
			TarPath:   entry.tarPath,
		})
	}
	return tarEntries
}

func (fte *flowToolsExecutor) cachedUploadsDir() (string, error) {
	dataDir, err := filepath.Abs(fte.cfg.DataDir)
	if err != nil {
		return "", fmt.Errorf("failed to resolve data directory: %w", err)
	}

	return flowfiles.FlowUploadsDir(dataDir, uint64(fte.flowID)), nil
}

func (fte *flowToolsExecutor) cachedResourcesDir() (string, error) {
	dataDir, err := filepath.Abs(fte.cfg.DataDir)
	if err != nil {
		return "", fmt.Errorf("failed to resolve data directory: %w", err)
	}

	return flowfiles.FlowResourcesDir(dataDir, uint64(fte.flowID)), nil
}

func (fte *flowToolsExecutor) Release(ctx context.Context) error {
	if fte.store != nil {
		// Do NOT close the store when it is backed by the shared pgxpool — the pool
		// outlives individual flows and is shared by all executors. Only close when

View on GitHub (pinned to ea665308ba)

Solutions

  1. Restart the backend process from a valid existing working directory
  2. Configure DataDir as an absolute path (e.g. /data) so filepath.Abs is independent of CWD — set DATA_DIR in .env/docker-compose
  3. Check the process still has a valid CWD: ls -l /proc/<pid>/cwd
  4. Fix deployment unit files (systemd WorkingDirectory, Docker WORKDIR) so the start directory exists and persists

Example fix

// before
dataDir, err := filepath.Abs(fte.cfg.DataDir)
if err != nil {
	return "", fmt.Errorf("failed to resolve data directory: %w", err)
}
// after (config side) — make DataDir absolute at load time
if !filepath.IsAbs(cfg.DataDir) {
	return "", fmt.Errorf("DATA_DIR must be an absolute path, got %q", cfg.DataDir)
}
Defensive patterns

Strategy: validation

Validate before calling

// at config load time
if cfg.DataDir == "" {
	return errors.New("DATA_DIR is not set")
}
if !filepath.IsAbs(cfg.DataDir) {
	abs, err := filepath.Abs(cfg.DataDir) // fails only if CWD is gone
	if err != nil {
		return fmt.Errorf("cannot resolve relative DATA_DIR %q: %w", cfg.DataDir, err)
	}
	cfg.DataDir = abs
}
if err := os.MkdirAll(cfg.DataDir, 0o755); err != nil {
	return err
}

Try / catch

dir, err := fte.cachedUploadsDir()
if err != nil {
	// fall back to an absolute default location instead of failing the flow
	log.Warn().Err(err).Msg("data dir resolve failed; using fallback")
	dir = "/data/flow-uploads"
}

Prevention

When it happens

Trigger: filepath.Abs(fte.cfg.DataDir) returns an error because os.Getwd fails: the process's current working directory was removed, or getwd is unavailable (restricted environment).

Common situations: Backend binary started in a directory that was later deleted (e.g. temp dir cleanup while running under systemd/tmux/CI); DataDir configured as a relative path making it depend on CWD; containers where WORKDIR was removed at runtime.

Related errors


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