sxyazi/yazi · error

Target URL must be absolute

Error message

Target URL must be absolute

What it means

The `mgr:displace` actor requires the replacement target URL to be absolute. Relative or fragmentary URLs cannot unambiguously identify a filesystem location to displace the current directory entry with, so the actor rejects them up front before any file operations run.

Solutions

  1. Make the target absolute: join the user input onto the current directory (`cwd.join(input)` or `old.parent().unwrap().try_join(name)`) before calling `mgr:displace`
  2. Validate with `to.is_absolute()` in your plugin and show a user-facing message instead of calling the actor
  3. If the input came from a prompt, configure it to prepend the current working directory automatically

Example fix

// before
act!(mgr:displace, cx, (to, true))?  // to = "foo.txt"
// after
let to = if to.is_absolute() { to } else { cx.cwd().try_join(to)? };
act!(mgr:displace, cx, (to, true))?
Defensive patterns

Strategy: validation

Validate before calling

if !to.is_absolute() {
    anyhow::bail!("displace target must be absolute, got: {to}");
}
act!(mgr:displace, cx, (to, true))?;

Type guard

fn is_absolute_target(url: &Url) -> bool {
    url.is_absolute()
}

Try / catch

match mgr_displace(cx, to).await {
    Err(e) if e.to_string().contains("Target URL must be absolute") => {
        // retry with cwd-joined URL
        let abs = cx.cwd().join(to);
        mgr_displace(cx, abs).await?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Invoking the `displace` command/plugin (`mgr:displace`) with a `to` URL that fails `Url::is_absolute()` — e.g. a bare relative name like `foo.txt`, a scheme-only URL, or a path missing its leading component.

Common situations: User types a relative name into the displace input prompt; a custom keymap or shell integration passes a partially-constructed URL; a plugin builds the target with string concatenation instead of joining onto an absolute base.

Related errors


AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02). Data as JSON: /api/errors/254af54cc0a8a8a8. Report an issue: GitHub.

Appendix: source

Thrown at yazi-actor/src/mgr/displace_do.rs:28

pub struct DisplaceDo;

impl Actor for DisplaceDo {
	type Form = DisplaceDoForm;

	const NAME: &str = "displace_do";

	fn act(cx: &mut Ctx, Self::Form { opt }: Self::Form) -> Result<Data> {
		if cx.cwd() != opt.from {
			succ!()
		}

		let to = match opt.to {
			Ok(url) => url,
			Err(e) => return act!(mgr:update_files, cx, FilesOp::IOErr(opt.from, e)),
		};

		if !to.is_absolute() {
			bail!("Target URL must be absolute");
		} else if let Some(hovered) = cx.hovered()
			&& let Ok(url) = to.try_join(hovered.urn())
		{
			act!(mgr:reveal, cx, (url, CdSource::Displace))
		} else {
			act!(mgr:cd, cx, (to, CdSource::Displace))
		}
	}
}

View on GitHub (pinned to 5f901b886b)