Tencent/WeKnora · error

storage directory not accessible: %w

Error message

storage directory not accessible: %w

What it means

localFileService.CheckConnectivity wraps os.Stat errors on s.baseDir with "storage directory not accessible: %w". It runs during health/connectivity checks to verify local file storage is usable. The wrapped error is almost always "no such file or directory" (ENOSQL dir missing) or "permission denied".

Source

Thrown at internal/application/service/file/local.go:30

	"github.com/Tencent/WeKnora/internal/logger"
	"github.com/Tencent/WeKnora/internal/types/interfaces"
	secutils "github.com/Tencent/WeKnora/internal/utils"
)

// localFileService implements the FileService interface for local file system storage
type localFileService struct {
	baseDir     string // Base directory for file storage
	externalURL string // External URL base for presigned URL generation (empty = return local:// paths)
}

const localScheme = "local://"

// CheckConnectivity verifies the local storage directory exists and is accessible.
func (s *localFileService) CheckConnectivity(ctx context.Context) error {
	info, err := os.Stat(s.baseDir)
	if err != nil {
		return fmt.Errorf("storage directory not accessible: %w", err)
	}
	if !info.IsDir() {
		return fmt.Errorf("storage path is not a directory: %s", s.baseDir)
	}
	return nil
}

// NewLocalFileService creates a new local file service instance.
// externalURL is the externally-reachable base URL (e.g. "https://weknora.example.com");
// when set, GetFileURL returns presigned HTTP URLs instead of local:// paths.
func NewLocalFileService(baseDir, externalURL string) interfaces.FileService {
	return &localFileService{
		baseDir:     baseDir,
		externalURL: strings.TrimRight(externalURL, "/"),
	}
}

// SaveFile stores an uploaded file to the local file system

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Create the configured base directory: mkdir -p <LOCAL_STORAGE_BASE_DIR> (SaveFile creates subdirs, but the base itself must exist for connectivity checks).
  2. Check the storage config/LOCAL_FILE_BASE_DIR env var points to the intended absolute path, not a typo or a path removed in a newer image.
  3. Fix ownership/permissions so the service user can read/stat the directory (e.g. chown -R appuser:appuser /data/files, chmod 755).
  4. In containerized deployments, verify the volume mount exists and is mounted (docker inspect / kubectl describe pod) and the PVC is Bound.

Example fix

// before
// LOCAL_FILE_BASE_DIR=/data/weknora/files  (dir missing in container)
// after
// Dockerfile / entrypoint
RUN mkdir -p /data/weknora/files && chown -R appuser /data/weknora/files
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(baseDir)
if err != nil || !info.IsDir() {
	return fmt.Errorf("base dir %q unusable: %v", baseDir, err)
}

Try / catch

if err := svc.CheckConnectivity(ctx); err != nil {
	log.Fatalf("local storage unavailable: %v", err) // fail fast at boot
}

Prevention

When it happens

Trigger: os.Stat(baseDir) fails: the LOCAL_STORAGE_BASE_DIR directory doesn't exist, was deleted at runtime, is on an unmounted volume, or the process lacks read permission on it.

Common situations: Docker/K8s volume not mounted or mount path typo; fresh deployment where the data dir was never created; running container as non-root user while dir is root-owned; base dir on a detached PVC or host path that changed between restarts.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/a66fd35e52e873b5. Report an issue: GitHub.