larksuite/cli · error

invalid profile name %q: contains control characters

Error message

invalid profile name %q: contains control characters

What it means

ValidateProfileName scans each rune and rejects control characters (0x1F and below or the equivalent class), which cannot be typed safely into shells or stored reliably - while Unicode letters remain allowed.

Source

Thrown at internal/core/config.go:170

	for i := range m.Apps {
		names[i] = m.Apps[i].ProfileName()
	}
	return names
}

// ValidateProfileName checks that a profile name is valid.
// Rejects empty names, whitespace, control characters, and shell-problematic characters,
// but allows Unicode letters (e.g. Chinese, Japanese) for localized profile names.
func ValidateProfileName(name string) error {
	if name == "" {
		return fmt.Errorf("profile name cannot be empty")
	}
	if utf8.RuneCountInString(name) > 64 {
		return fmt.Errorf("profile name %q is too long (max 64 characters)", name)
	}
	for _, r := range name {
		if r <= 0x1F || r == 0x7F { // control characters
			return fmt.Errorf("invalid profile name %q: contains control characters", name)
		}
		switch r {
		case ' ', '\t', '/', '\\', '"', '\'', '`', '$', '#', '!', '&', '|', ';', '(', ')', '{', '}', '[', ']', '<', '>', '?', '*', '~':
			return fmt.Errorf("invalid profile name %q: contains invalid character %q", name, r)
		}
	}
	return nil
}

// CliConfig is the resolved single-app config used by downstream code.
type CliConfig struct {
	ProfileName         string
	AppID               string
	AppSecret           string
	Brand               LarkBrand
	DefaultAs           Identity // AsUser | AsBot | AsAuto | "" (from config file)
	UserOpenId          string
	UserName            string

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Strip control characters before passing the name: trim whitespace and remove \x00-\x1F and \x7F
  2. Fix the source string (e.g. strings.TrimRight(name, "\r\n")) where the name is produced
  3. Choose a simple printable ASCII or Unicode-letter name

Example fix

// before
name := strings.TrimSpace(rawName)
// after
name := strings.Map(func(r rune) rune {
    if r <= 0x1F || r == 0x7F { return -1 }
    return r
}, strings.TrimSpace(rawName))
Defensive patterns

Strategy: validation

Validate before calling

func sanitizeProfileName(s string) string {
    return strings.Map(func(r rune) rune {
        if r <= 0x1F || r == 0x7F { return -1 }
        return r
    }, strings.TrimSpace(s))
}

Try / catch

if err := core.ValidateProfileName(name); err != nil {
    if strings.Contains(err.Error(), "control characters") {
        return fmt.Errorf("re-check where the name came from (clipboard/paste); %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: A name containing newlines, tabs-embedded control bytes, ANSI escapes, or a lone DEL character reaches ValidateProfileName via auth init/add/rename.

Common situations: Copy-pasting a name with a trailing newline from a terminal; programmatically building names from raw API strings containing escape sequences; bad shell interpolation inserting CR (\r) on Windows.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/dfd7b1d8de8b250c. Report an issue: GitHub.