larksuite/cli · error
%s contains invalid characters
Error message
%s contains invalid characters
What it means
ResourceName checks the identifier against the unsafeResourceChars pattern and rejects it if any disallowed character is present. This prevents characters that could alter URL structure or request semantics (e.g. '?', '#') from reaching the endpoint. The message names the offending flag.
Source
Thrown at internal/validate/resource.go:37
// 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 known
// dangerous patterns at the input layer, while EncodePathSegment acts as a fallback
// at the concatenation layer — if ResourceName rules are relaxed in the future, or
// if an API path bypasses ResourceName validation (e.g. cmd/service/ generic calls),
// encoding still prevents special characters from being interpreted as path separatorsView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Trim whitespace and copy only the exact identifier token.
- Remove URL fragments/query parts if the ID was copied from a full URL.
- Quote variables in shell to avoid stray characters from word splitting.
- Use EncodePathSegment if the input legitimately needs URL-unsafe characters.
Example fix
// before lark-cli im message get --message-id "om_abc?trace=1" // after lark-cli im message get --message-id "om_abc"
Defensive patterns
Strategy: validation
Validate before calling
id = strings.TrimSpace(id)
if strings.ContainsAny(id, "?# \t") {
return fmt.Errorf("id contains URL-significant or whitespace characters")
} Try / catch
if err := validate.ResourceName(id, "--message-id"); err != nil {
return fmt.Errorf("clean the id (no query/fragment chars): %w", err)
} Prevention
- Trim whitespace from all CLI inputs.
- Copy IDs as bare tokens, never full URLs with query strings or fragments.
- Quote shell variables to prevent word-splitting artifacts.
- Run validate.ResourceName (or equivalent) in your own tooling before shelling out.
When it happens
Trigger: validate.ResourceName receives a name matching unsafeResourceChars — URL-significant characters like '?', '#', or whitespace/control characters in an ID flag.
Common situations: Copying IDs including surrounding URL fragments or query strings, trailing whitespace from copy-paste, spaces introduced by shell word splitting, or injection attempts via '?evil=true'-style input.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- %s contains invalid line break characters
- %s must not be empty
- %s must not contain '..' path traversal
- %s contains dangerous Unicode characters
- only http/https URLs are supported
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/247f46bf2f539c0a.
Report an issue: GitHub.