gastownhall/beads · error

directory path is empty

Error message

directory path is empty

What it means

MeasureDirectorySize measures the approximate size of a live file tree, but rejects an empty root path up front with this sentinel error rather than attempting a walk. It is a caller-contract validation error, not a filesystem failure.

Source

Thrown at internal/storage/directory_size.go:20

import (
	"context"
	"errors"
	"fmt"
	"io/fs"
	"math"
	"os"
	"path/filepath"
)

type directoryWalkFunc func(string, filepath.WalkFunc) error

// MeasureDirectorySize returns the approximate size of the live file tree at
// root. It tolerates descendants disappearing while the tree is being walked,
// but a missing root or any other filesystem error is a failed measurement.
func MeasureDirectorySize(ctx context.Context, root string) (int64, error) {
	if root == "" {
		return 0, fmt.Errorf("directory path is empty")
	}

	resolvedRoot, err := filepath.EvalSymlinks(root)
	if err != nil {
		return 0, err
	}
	info, err := os.Stat(resolvedRoot)
	if err != nil {
		return 0, err
	}
	if !info.IsDir() {
		return 0, fmt.Errorf("%s is not a directory", root)
	}

	return measureDirectorySizeWithWalk(ctx, resolvedRoot, filepath.Walk)
}

func measureDirectorySizeWithWalk(ctx context.Context, root string, walk directoryWalkFunc) (int64, error) {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Validate the root path is non-empty before calling; check the config/flag that supplies it
  2. Fail fast at startup with a clear 'data directory not configured' message
  3. Apply os.Getenv/flag defaults so the directory setting can never be empty in practice

Example fix

// before
size, err := storage.MeasureDirectorySize(ctx, cfg.DataDir) // cfg.DataDir == ""
// after
if cfg.DataDir == "" {
    return fmt.Errorf("data directory not configured")
}
size, err := storage.MeasureDirectorySize(ctx, cfg.DataDir)
Defensive patterns

Strategy: validation

Validate before calling

func validateRoot(root string) error {
    if strings.TrimSpace(root) == "" {
        return fmt.Errorf("data directory not configured")
    }
    return nil
}
// call before MeasureDirectorySize

Try / catch

if err := validateRoot(cfg.DataDir); err != nil { return err }
size, err := storage.MeasureDirectorySize(ctx, cfg.DataDir)
if err != nil { return fmt.Errorf("measure %s: %w", cfg.DataDir, err) }

Prevention

When it happens

Trigger: MeasureDirectorySize(ctx, "") — passing an uninitialized/empty string variable for the directory root, e.g. a config field that was never populated.

Common situations: Config struct not filled in (missing CLI flag or env var default); a path variable shadowed/zeroed by an earlier error path; programmatic callers constructing the root via string concatenation that produced "".

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/f84cd082492e5515. Report an issue: GitHub.