multica-ai/multica · error

remove stale %s copy %s: %w

Error message

remove stale %s copy %s: %w

What it means

Before copying a fresh copy of a config file into the task home, a stale existing copy is removed via root.Remove. Failure means the old file could not be deleted: it is a non-empty directory, permissions deny unlink, or the path crossed an escaping symlink (rejected by os.Root).

Source

Thrown at server/internal/daemon/execenv/codex_home.go:1024

// else would have the daemon delete and overwrite the link target on the next
// prepare. os.Root still allows links that stay inside the task home, which is
// harmless, and rejects the ones that leave it. The root itself is
// identity-checked by openVerifiedCodexHomeRoot.
func materialiseInCodexHome(codexHome, relPath, src, key string) error {
	root, err := openVerifiedCodexHomeRoot(codexHome, key)
	if err != nil {
		return err
	}
	defer root.Close()

	if dir := filepath.Dir(relPath); dir != "." {
		if err := root.MkdirAll(dir, 0o755); err != nil {
			return fmt.Errorf("create %s directory %s: %w", key, dir, err)
		}
	}
	if _, err := root.Lstat(relPath); err == nil {
		if err := root.Remove(relPath); err != nil {
			return fmt.Errorf("remove stale %s copy %s: %w", key, relPath, err)
		}
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("stat %s copy %s: %w", key, relPath, err)
	}

	in, err := os.Open(src)
	if err != nil {
		return fmt.Errorf("open %s %s: %w", key, src, err)
	}
	defer in.Close()

	out, err := root.OpenFile(relPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o644)
	if err != nil {
		return fmt.Errorf("create %s copy %s: %w", key, relPath, err)
	}
	defer out.Close()

	if _, err := io.Copy(out, in); err != nil {

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Manually inspect and remove the stale entry under the task home
  2. Recreate the task home if the stale entry is unexpected
  3. Verify the daemon user can write to the task home
Defensive patterns

Strategy: fallback

Validate before calling

if fi, err := os.Lstat(filepath.Join(codexHome, relPath)); err == nil && fi.IsDir() {
	return fmt.Errorf("cannot replace directory %s with file copy", relPath)
}

Prevention

When it happens

Trigger: relPath exists as a directory with children; the daemon lacks write permission on the containing directory; the existing entry is a symlink whose target resolution os.Root refuses.

Common situations: A task replaced a config path (e.g. auth.json) with a directory of its own; reused home with corrupted state.

Related errors


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