multica-ai/multica · error
create %s directory %s: %w
Error message
create %s directory %s: %w
What it means
materialiseInCodexHome calls root.MkdirAll for the parent directories of the destination (e.g. the parent of a config file copy) inside the verified os.Root. Failure means the intermediate directory could not be created: a non-directory file exists in the way, permissions, or a symlink leaves the root (os.Root rejects links that escape the task home).
Source
Thrown at server/internal/daemon/execenv/codex_home.go:1019
// daemon's mkdir, remove, or write outside it.
//
// This matters because a task home is reused: a prepare can run against a
// directory a previous task already wrote to. Without the root, a task that
// replaced an intermediate directory of its own home with a link to somewhere
// 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 {View on GitHub (pinned to 2c0912b6ec)
Solutions
- Inspect the offending intermediate path under the task home and remove the blocking file or escaping symlink
- Reset/recreate the task home if its contents are untrusted
- Check filesystem write permissions for the daemon user
Defensive patterns
Strategy: validation
Validate before calling
dir := filepath.Join(codexHome, filepath.Dir(relPath))
if fi, err := os.Lstat(dir); err == nil && !fi.IsDir() {
return fmt.Errorf("blocked path %s is not a directory", dir)
} Prevention
- Reset task homes between untrusted tasks
- Ensure no escaping symlinks exist on config subpaths before prepare
When it happens
Trigger: A previous task left a regular file where a directory is needed; a symlinked intermediate directory points outside the task home; read-only filesystem.
Common situations: Reused task home polluted by earlier task output; a task linked an intermediate dir to /tmp or another task's area.
Related errors
- codex home %s is a symlink; refusing to write %s through it
- resolve --%s path %q: %w
- resolve --attachment path %q: %w
- resolve symlink: %w
- open codex home %s: %w
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/28249530378304bf.
Report an issue: GitHub.