multica-ai/multica · error
--%s path %q resolves outside the current working directory;
Error message
--%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.
What it means
A file-content flag (--description-file, --content-file, etc.) points to a path that resolves outside the process working directory. The CLI enforces this to prevent a stale-file content leak: an earlier incident had one run silently read a /tmp file written by a different run. The check is symlink-aware on both sides, so aliasing a path into the workdir via symlink does not bypass it.
Source
Thrown at server/cmd/multica/cmd_issue.go:112
//
// 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.
func fileWithinWorkingDir(filePath string) (bool, error) {
cwd, err := os.Getwd()
if err != nil {View on GitHub (pinned to 2c0912b6ec)
Solutions
- Write the temp file inside the current working directory (e.g. ./desc.md) as the error message suggests, then re-run.
- If the outside location is intentional and you accept the stale-file risk, add --allow-external-file to the command.
- If you expected the path to be inside the workdir, check for symlinks (realpath <path>) — the guard resolves them, so the physical location is what counts.
- Verify the process is running from the directory you think (pwd), since the boundary is the CWD, not the repo root.
Example fix
# before printf 'content' > /tmp/desc.md multica issue create --title T --description-file /tmp/desc.md # after printf 'content' > ./desc.md multica issue create --title T --description-file ./desc.md
Defensive patterns
Strategy: validation
Validate before calling
# ensure the file is physically inside the CWD (symlinks resolved) case "$(realpath "$DESC_FILE")" in "$(realpath .)"/*) ;; *) echo "file outside workdir" >&2; exit 1;; esac
Prevention
- Always write agent scratch files into the task workdir (./name.md), never /tmp.
- Treat --allow-external-file as an explicit, audited exception — not a default in scripts.
- Remember the boundary is the process CWD: run the CLI from the directory containing the files.
When it happens
Trigger: Passing an absolute path like /tmp/desc.md, a relative path that climbs out of the workdir (../../shared/desc.md), or a workdir symlink pointing to an outside location — unless --allow-external-file is set. fileWithinWorkingDir resolves symlinks on both the file and the working directory, so macOS /tmp -> /private/tmp style aliases are still detected.
Common situations: Agents/scripts writing scratch files to /tmp or other machine-shared dirs and feeding them to the CLI; CI jobs sharing a temp dir between parallel runs; a symlink inside the repo pointing at a home-directory file.
Related errors
- --attachment path %q resolves outside the current working di
- 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/9793e1c78d3e571f.
Report an issue: GitHub.