larksuite/cli · error
%s contains dangerous Unicode characters
Error message
%s contains dangerous Unicode characters
What it means
ResourceName iterates the identifier's runes and rejects any character for which charcheck.IsDangerousUnicode returns true — e.g. bidi controls, zero-width, or homoglyph-confusable characters. This stops visually deceptive or control-bearing IDs from being sent to the API. The flag name identifies which input to correct.
Source
Thrown at internal/validate/resource.go:41
//
// 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 separators
// or query parameters.
//
// Convention: all user-provided variables in fmt.Sprintf API paths within shortcuts/
// MUST be wrapped with this function.View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Re-copy the ID from a plain-text source (terminal, API JSON) rather than rich text.
- Strip invisible characters with a Unicode-stripping filter before use.
- Fetch the canonical ID again via the API (list/search) instead of pasting.
- Inspect the input with `hexdump -C` to find hidden characters.
Example fix
// before
lark-cli im message get --message-id "$ID" # ID copied from a doc, contains U+200B
// after
ID=$(printf '%s' "$ID" | perl -CS -pe 's/[\x{200B}-\x{200F}\x{202A}-\x{202E}\x{FEFF}]//g')
lark-cli im message get --message-id "$ID" Defensive patterns
Strategy: validation
Validate before calling
for _, r := range id {
if charcheck.IsDangerousUnicode(r) {
return fmt.Errorf("id contains dangerous Unicode (bidi/zero-width) characters")
}
} Try / catch
if err := validate.ResourceName(id, "--message-id"); err != nil {
return fmt.Errorf("re-copy the id from a plain-text source: %w", err)
} Prevention
- Copy identifiers from plain-text sources, not rich-text documents or chat bubbles.
- Strip zero-width/bidi/control characters programmatically before use.
- Re-fetch canonical IDs via API list/search endpoints instead of pasting.
- Inspect suspicious inputs with hexdump to detect invisible characters.
When it happens
Trigger: validate.ResourceName receives a name containing dangerous Unicode (bidi/zero-width/control characters), detected per-rune via charcheck.IsDangerousUnicode.
Common situations: IDs copy-pasted from rich-text documents or chat messages carrying invisible formatting characters, CSV/spreadsheet exports with BOM or zero-width spaces, or crafted spoofed identifiers.
Related errors
- %s contains dangerous Unicode characters
- %s contains invalid line break characters
- %s must not contain '..' path traversal
- %s contains invalid characters
- only http/https URLs are supported
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/dd7c44e61dfac011.
Report an issue: GitHub.