juicedata/juicefs · error
unescape %s: %s
Error message
unescape %s: %s
What it means
In `juicefs sync`, when a source/destination URI uses the `jfs` scheme, the volume name is carried in the URL host and may be percent-encoded. createSyncStorage calls url.PathUnescape on it; this error is returned when that unescaping fails, meaning the host component contains a malformed escape sequence such as `%zz` or a lone trailing `%`.
Source
Thrown at cmd/sync.go:420
logger.Fatalf("Can't parse %q: %s", utils.RemovePassword(uri), utils.RemovePassword(err.Error()))
}
user := u.User
var accessKey, secretKey string
if user != nil {
accessKey = user.Username()
secretKey, _ = user.Password()
}
name := strings.ToLower(u.Scheme)
var endpoint string
if name == "file" {
endpoint = u.Path
} else if name == "hdfs" {
endpoint = u.Host
} else if name == "jfs" {
endpoint, err = url.PathUnescape(u.Host)
if err != nil {
return nil, fmt.Errorf("unescape %s: %s", u.Host, err)
}
if os.Getenv(endpoint) != "" {
conf.Env[endpoint] = os.Getenv(endpoint)
}
} else if name == "nfs" {
endpoint = u.Host + u.Path
} else if !conf.NoHTTPS && supportHTTPS(name, u.Host) {
endpoint = "https://" + u.Host
} else {
endpoint = "http://" + u.Host
}
isS3PathTypeUrl := isS3PathType(u.Host)
if name == "minio" || name == "s3" && isS3PathTypeUrl {
// bucket name is part of path
endpoint += u.Path
}
View on GitHub (pinned to c9a67b23e8)
Solutions
- Fix the URI so every '%' is followed by two hex digits, or remove unnecessary encoding entirely (e.g. `jfs://myvol` instead of `jfs://my%vol`)
- Percent-encode properly: `%` itself becomes `%25` (use python3 -c 'import urllib.parse;print(urllib.parse.quote(name))')
- If no special characters are in the volume name, use the raw name unencoded
Example fix
// before jfs://vol%zz/subdir # invalid escape // after jfs://vol%25zz/subdir # '%25' is an encoded '%'
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(uri)
if err == nil && u.Scheme == "jfs" {
if _, err := url.PathUnescape(u.Host); err != nil {
return fmt.Errorf("bad jfs URI host %q: %w", u.Host, err)
}
} Type guard
null
Try / catch
store, err := createSyncStorage(...)
if err != nil && strings.HasPrefix(err.Error(), "unescape ") {
// fix the URI or surface a config error to the user
} Prevention
- Percent-encode '%' as %25 when building jfs:// URIs programmatically
- Avoid manual string concatenation of escape sequences into URIs
- Test the URI with url.Parse + PathUnescape in scripts
When it happens
Trigger: Calling doSync (or createSyncStorage) with a `jfs://` URI whose host contains an invalid percent-escape, e.g. `jfs://vol%2name/` or `jfs://my%vol/`. Any byte after '%' that is not two hex digits causes url.PathUnescape to fail.
Common situations: Manually percent-encoding a volume name containing special characters and getting the encoding wrong; scripts building URIs with printf/shell substitutions that mangle '%'; copying a URL that was encoded with a non-URL scheme.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/38447959c5c70048.
Report an issue: GitHub.