sipeed/picoclaw · error

source is required

Error message

source is required

What it means

ValidateExposePaths rejects any isolation.expose_paths entry whose Source is the empty string. Source identifies the host path to expose into the isolated child, so an entry without it is meaningless and preflight fails fast instead of launching a child with a silently ignored rule.

Source

Thrown at pkg/isolation/runtime.go:167

		envMap["XDG_CONFIG_HOME"] = userEnv.Config
		envMap["XDG_CACHE_HOME"] = userEnv.Cache
		envMap["XDG_STATE_HOME"] = userEnv.State
	}

	env := make([]string, 0, len(envMap))
	for k, v := range envMap {
		env = append(env, fmt.Sprintf("%s=%s", k, v))
	}
	cmd.Env = env
}

// ValidateExposePaths verifies the user-supplied path exposure rules before a
// child process is started.
func ValidateExposePaths(items []config.ExposePath) error {
	seen := map[string]struct{}{}
	for _, item := range items {
		if item.Source == "" {
			return fmt.Errorf("source is required")
		}
		if item.Mode != "ro" && item.Mode != "rw" {
			return fmt.Errorf("invalid expose_paths mode: %s", item.Mode)
		}

		source := filepath.Clean(item.Source)
		target := item.Target
		if target == "" {
			target = source
		}
		target = filepath.Clean(target)

		if !filepath.IsAbs(source) || !filepath.IsAbs(target) {
			return fmt.Errorf("source and target must be absolute paths")
		}
		if _, ok := seen[target]; ok {
			return fmt.Errorf("duplicate expose_path target: %s", target)
		}

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Set a non-empty, absolute source path on every expose_paths entry
  2. If the entry was accidental, delete it instead of leaving an empty rule
  3. Double-check field order/names — a target-only entry means the source was probably lost during editing

Example fix

# before
isolation:
  expose_paths:
    - target: /workspace
      mode: rw

# after
isolation:
  expose_paths:
    - source: /home/me/project
      target: /workspace
      mode: rw
Defensive patterns

Strategy: validation

Validate before calling

for _, p := range cfg.Isolation.ExposePaths {
    if strings.TrimSpace(p.Source) == "" {
        return fmt.Errorf("expose_paths entry with target %q is missing source", p.Target)
    }
}

Try / catch

if err := isolation.ValidateExposePaths(cfg.Isolation.ExposePaths); err != nil {
    return fmt.Errorf("isolation config rejected at load time: %w", err)
}

Prevention

When it happens

Trigger: A config entry like {target: "/data", mode: "ro"} with source omitted, or source: "" explicitly; commonly a typo where source/target fields are swapped or a template placeholder was never filled in.

Common situations: Hand-edited YAML/JSON isolation config; config generated from a template where the source variable was empty; merging configs where the source key was dropped.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/b022fba6c2fee9a2. Report an issue: GitHub.