vxcontrol/pentagi · critical

failed to create tmp directory: %w

Error message

failed to create tmp directory: %w

What it means

After resolving the data directory, NewDockerClient calls os.MkdirAll(dataDir, 0755) to guarantee the per-flow working directory root exists (it is bind-mounted into sandbox containers). Any filesystem failure creating that directory is wrapped as "failed to create tmp directory: %w". This is a real I/O error, unlike error 251: the path resolution succeeded but the directory could not be created.

Source

Thrown at backend/pkg/docker/client.go:171

				"container, so any process inside it gets control of the same daemon that runs " +
				"PentAGI. Set DOCKER_SOCKET or DOCKER_INSIDE_HOST explicitly, or front the socket " +
				"with a least-privilege proxy (e.g. Tecnativa/docker-socket-proxy), if that is not intended.")
		}
	}
	netName := cfg.DockerNetwork
	publicIP := cfg.DockerPublicIP
	defImage := strings.ToLower(cfg.DockerDefaultImage)
	if defImage == "" {
		defImage = defaultImage
	}

	dataDir, err := filepath.Abs(cfg.DataDir)
	if err != nil {
		return nil, fmt.Errorf("failed to get absolute path: %w", err)
	}

	if err := os.MkdirAll(dataDir, 0755); err != nil {
		return nil, fmt.Errorf("failed to create tmp directory: %w", err)
	}

	hostDir := getHostDataDir(ctx, cli, dataDir, cfg.DockerWorkDir)

	// ensure network exists if configured
	if err := ensureDockerNetwork(ctx, cli, netName); err != nil {
		return nil, fmt.Errorf("failed to ensure docker network %s: %w", netName, err)
	}

	logger := logrus.StandardLogger()
	logger.WithFields(logrus.Fields{
		"docker_name":        info.Name,
		"docker_arch":        info.Architecture,
		"docker_version":     info.ServerVersion,
		"client_version":     cli.ClientVersion(),
		"data_dir":           dataDir,
		"host_dir":           hostDir,
		"docker_inside":      inside,

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check ownership/permissions on DATA_DIR and its parents; chown to the user running PentAGI (chown -R 1000:1000 /var/lib/pentagi).
  2. Verify the path is not an existing regular file; remove or rename the file, or choose another DATA_DIR.
  3. Remove any 'ro' flag on the DATA_DIR volume mount in docker-compose.yml.
  4. Check disk space (df -h) and SELinux denials (ausearch -m avc) if permissions look correct.

Example fix

// before (docker-compose.yml)
volumes:
  - /var/lib/pentagi/data:/data:ro
// after
volumes:
  - /var/lib/pentagi/data:/data
Defensive patterns

Strategy: validation

Validate before calling

func ensureDataDirWritable(path string) error {
    st, err := os.Stat(path)
    if err == nil && !st.IsDir() {
        return fmt.Errorf("%s exists and is not a directory", path)
    }
    probe := filepath.Join(path, ".write-probe")
    if err := os.WriteFile(probe, nil, 0644); err != nil {
        return fmt.Errorf("DATA_DIR not writable: %w", err)
    }
    os.Remove(probe)
    return nil
}
// call ensureDataDirWritable(cfg.DataDir) before NewDockerClient

Try / catch

if _, err := NewDockerClient(ctx, db, cfg); err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && errors.Is(pe, os.ErrPermission) {
        log.Fatalf("cannot create DATA_DIR %s: %v — chown/chmod the path", cfg.DataDir, err)
    }
    return err
}

Prevention

When it happens

Trigger: os.MkdirAll(dataDir, 0755) fails: parent path component is a regular file, permission denied, read-only filesystem, disk full, or SELinux/AppArmor denies creation at that path.

Common situations: DATA_DIR points under a path owned by root while the app runs as non-root; a file already exists where a directory is expected (leftover from a bad cleanup); mounting DATA_DIR as a read-only volume in Docker Compose; SELinux denial on a custom path; full disk on a small VM.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


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