multica-ai/multica · error

local_directory: local_path is empty

Error message

local_directory: local_path is empty

What it means

Returned by normalizeLocalPath in server/internal/daemon/local_directory.go when the local_directory runtime's local_path value is empty after trimming whitespace. The function is the first normalization step for local-directory task sources: it strips whitespace, requires an absolute path, and cleans it — an empty input can never resolve to a working directory, so it fails before any filesystem access (the function deliberately does no stat/symlink work).

Source

Thrown at server/internal/daemon/local_directory.go:165

		if err != nil {
			return nil, err
		}
		match = &localDirectoryAssignment{
			Ref:      ref,
			AbsPath:  absPath,
			RealPath: realPath,
		}
	}
	return match, nil
}

// normalizeLocalPath strips whitespace and resolves the path to an absolute
// cleaned form. It does NOT touch the filesystem (no symlink resolution, no
// existence check) — callers do that separately via validateLocalPath.
func normalizeLocalPath(p string) (string, error) {
	trimmed := strings.TrimSpace(p)
	if trimmed == "" {
		return "", errors.New("local_directory: local_path is empty")
	}
	if !filepath.IsAbs(trimmed) {
		return "", fmt.Errorf("local_directory: local_path must be absolute, got %q", trimmed)
	}
	return filepath.Clean(trimmed), nil
}

// resolveRealPath returns the symlink-resolved absolute form of path. The
// path mutex keys on this value so a task on `/Users/u/proj` and another on
// `/private/var/folders/.../proj-symlink → /Users/u/proj` collapse to one
// lock. When EvalSymlinks fails (path is missing or not yet a real link),
// fall back to the cleaned absolute form so callers can still proceed to
// the existence-check stage which surfaces a clearer error.
func resolveRealPath(absPath string) (string, error) {
	real, err := filepath.EvalSymlinks(absPath)
	if err != nil {
		// validateLocalPath will surface the underlying error with better
		// context; for the mutex key the cleaned absolute path is a safe

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Provide a non-empty, absolute path for local_path (e.g. /Users/me/projects/app).
  2. Validate the field in the UI/API client before submission: required, trimmed, and must start with '/'.
  3. If the path comes from a variable in automation, assert it is set before issuing the request.

Example fix

# before
{"source": {"type": "local_directory", "local_path": ""}}

# after
{"source": {"type": "local_directory", "local_path": "/home/me/code/proj"}}
Defensive patterns

Strategy: validation

Validate before calling

// Client-side, before creating a local_directory source
const path = String(localPath ?? "").trim();
if (!path || !path.startsWith("/")) {
  setError("local_path is required and must be absolute");
  return;
}

Type guard

function isValidLocalPathInput(p: unknown): boolean {
  return typeof p === "string" && p.trim() !== "" && p.trim().startsWith("/");
}

Prevention

When it happens

Trigger: Creating a local_directory runtime/task with local_path set to "", " ", or a value that is only whitespace; a form or API client sending the field unset because it treated it as optional; JSON payload built with local_path: undefined serialized as empty.

Common situations: UI form submitted without filling the path field; automation scripts templating the path from an unset variable; whitespace-only paste from a clipboard.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/a8639632f4504b92. Report an issue: GitHub.