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
- 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`
- Validate with `to.is_absolute()` in your plugin and show a user-facing message instead of calling the actor
- 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
- Resolve user input against cwd before passing to displace
- Add an is_absolute() assertion in plugin wrappers
- Avoid string-concatenating URLs; use try_join on an absolute base
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
- Cannot create file at root
- Failed to join new name with parent directory
- InvalidData
- atime not available
- btime not available
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)