multica-ai/multica · error
resolve --%s path %q: %w
Error message
resolve --%s path %q: %w
What it means
While enforcing that a --description-file/--content-file path stays inside the working directory, the CLI could not resolve the path at all (fileWithinWorkingDir returned an error). The %w wraps the underlying filesystem error, typically a stat or absolute-path resolution failure. The guard runs before the file is read, so this fires for paths the process cannot even resolve.
Source
Thrown at server/cmd/multica/cmd_issue.go:109
// ensureFileFlagWithinWorkdir fails closed when a --<name>-file path resolves
// outside the current working directory, unless --allow-external-file is set.
//
// Agent task workdirs are isolated per profile and per task; machine-shared
// scratch paths like /tmp are not. MUL-4252 traced a cross-environment context
// leak to exactly this gap: a quick-create run wrote its description to a fixed
// /tmp/desc.md, the write silently failed because a *different* environment's
// run had left a stale file there minutes earlier, and --description-file then
// fed that stale content into the new issue. Requiring the file to live under
// the workdir turns "silently read another run's file" into a loud command
// failure — an "incorrect content" bug becomes a "command errored" bug.
func ensureFileFlagWithinWorkdir(cmd *cobra.Command, fileFlag, flagName, filePath string) error {
if allow, _ := cmd.Flags().GetBool("allow-external-file"); allow {
return nil
}
within, err := fileWithinWorkingDir(filePath)
if err != nil {
return fmt.Errorf("resolve --%s path %q: %w", fileFlag, filePath, err)
}
if !within {
return fmt.Errorf(
"--%s path %q resolves outside the current working directory; "+
"write agent temp files inside the task workdir (e.g. ./%s.md) rather than machine-shared "+
"paths like /tmp, where another run's stale file can be read by mistake. "+
"Pass --allow-external-file to override.",
fileFlag, filePath, flagName)
}
return nil
}
// fileWithinWorkingDir reports whether filePath resolves to a location inside
// the process working directory. Both sides are symlink-resolved so aliased
// roots (e.g. macOS /tmp -> /private/tmp) and symlinks planted inside the
// workdir fail closed. A path that does not exist yet is judged on its cleaned
// absolute form so the caller's os.ReadFile still surfaces the real not-found
// error afterwards.View on GitHub (pinned to 2c0912b6ec)
Solutions
- Read the wrapped error (%w) — it carries the exact OS-level cause (ENOENT, EACCES, ELOOP, ESTALE).
- Run ls -l / realpath on the path to find the broken symlink or unmounted component and fix or recreate it.
- Point the flag at a real regular file inside the current working directory (e.g. ./desc.md).
- If the target legitimately sits outside the workdir and you accept the risk, pass --allow-external-file.
Example fix
# before (dangling symlink) ln -s /gone/desc.md desc.md multica issue create --title T --description-file desc.md # after printf 'real content' > ./desc.md multica issue create --title T --description-file ./desc.md
Defensive patterns
Strategy: validation
Validate before calling
# resolve the path first; a broken symlink or unresolvable path fails here with a clear message
realpath -e "$DESC_FILE" >/dev/null || { echo "cannot resolve $DESC_FILE" >&2; exit 1; } Prevention
- Use realpath -e on any file flag value before invoking the CLI.
- Avoid symlink indirection for scratch files; write plain files inside the workdir.
- Read the %w-wrapped cause in the error output — it names the exact OS failure.
When it happens
Trigger: Passing a --*-file value that fileWithinWorkingDir cannot resolve: a path with a component that errors on stat (e.g. a dangling symlink whose target is inaccessible), a path on an unmounted filesystem, or a path with a symlink loop. Note a plain nonexistent relative file may still resolve; the failure comes from the resolution step itself, and the wrapped error names the cause.
Common situations: Dangling symlinks left in a workdir by a previous run; NFS/automount paths that are stale; symlink cycles created by scripting mistakes; paths whose permissions deny traversal to the resolving user.
Related errors
- resolve --attachment path %q: %w
- file not found: %w
- unsupported file format %q: must be .png, .jpg, .jpeg, .gif,
- read file: %w
- read --%s-file: %w
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/9001c31641466aa6.
Report an issue: GitHub.