larksuite/cli · error
%s must not contain '..' path traversal
Error message
%s must not contain '..' path traversal
What it means
ResourceName splits the resource identifier on '/' and rejects any segment equal to '..', because path traversal could change which API endpoint the request targets (e.g. '../admin'). It is a defense-in-depth check alongside EncodePathSegment. The flag name is included so users know which input to fix.
Source
Thrown at internal/validate/resource.go:33
// unsafeResourceChars matches URL-special characters, control characters,
// and percent signs (to prevent %2e%2e encoding bypass).
var unsafeResourceChars = regexp.MustCompile(`[?#%\x00-\x1f\x7f]`)
// ResourceName validates an API resource identifier (messageId, fileToken, etc.)
// before it is interpolated into a URL path via fmt.Sprintf. It rejects path
// traversal (..), URL metacharacters (?#%), percent-encoded bypasses (%2e%2e),
// control characters, and dangerous Unicode.
//
// Without this check, an input like "../admin" or "?evil=true" in a message ID
// would alter the API endpoint the request is sent to. Works alongside
// EncodePathSegment for defense-in-depth.
func ResourceName(name, flagName string) error {
if name == "" {
return fmt.Errorf("%s must not be empty", flagName)
}
for _, seg := range strings.Split(name, "/") {
if seg == ".." {
return fmt.Errorf("%s must not contain '..' path traversal", flagName)
}
}
if unsafeResourceChars.MatchString(name) {
return fmt.Errorf("%s contains invalid characters", flagName)
}
for _, r := range name {
if charcheck.IsDangerousUnicode(r) {
return fmt.Errorf("%s contains dangerous Unicode characters", flagName)
}
}
return nil
}
// EncodePathSegment percent-encodes user input for safe use as a single URL path
// segment (e.g. / → %2F, ? → %3F, # → %23), ensuring the value cannot alter the
// URL routing structure when interpolated into an API path.
//
// This provides defense-in-depth alongside ResourceName: ResourceName rejects knownView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Use the actual opaque resource ID (e.g. om_xxx, app id) — not a path.
- Sanitize or reject path-like input before passing it; never build IDs from filesystem paths.
- If the ID was copied from a URL, extract only the final identifier segment.
- Use EncodePathSegment to percent-encode legitimate input containing slashes if the API expects encoded segments.
Example fix
// before id="$tenant/$msgID" lark-cli im message get --message-id "$id" // after lark-cli im message get --message-id "$msgID" # pass the bare om_xxx ID only
Defensive patterns
Strategy: validation
Validate before calling
for _, seg := range strings.Split(id, "/") {
if seg == ".." {
return fmt.Errorf("id must not contain path traversal")
}
} Try / catch
if err := validate.ResourceName(id, "--message-id"); err != nil {
return fmt.Errorf("rejecting unsuitable id: %w", err)
} Prevention
- Never construct API resource IDs from filesystem paths or user-controlled path fragments.
- Pass opaque IDs (om_xxx, app ids) exactly as returned by the API.
- Extract only the identifier segment when copying from URLs.
- Sanitize or reject path-like input at your application boundary.
When it happens
Trigger: validate.ResourceName receives a name containing a '/'-separated '..' segment — e.g. --message-id '../../admin' or an app ID built from untrusted path-like input.
Common situations: Passing filesystem-style relative paths where an API resource ID is expected, constructing IDs by concatenating user-controlled parts, or malicious input attempting endpoint manipulation.
Related errors
- %s contains invalid line break characters
- %s contains invalid characters
- %s contains dangerous Unicode characters
- only http/https URLs are supported
- Invalid cell reference: {cell_ref}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/bddf663992bb0a2b.
Report an issue: GitHub.