larksuite/cli · error
app ID must not be empty
Error message
app ID must not be empty
What it means
ForSubscribe builds a per-app subscribe lock filename from the app ID and rejects an empty app ID up front, because an empty ID would produce an ambiguous shared lock file ("subscribe_.lock") and indicates the caller never configured credentials. It returns a plain descriptive error (no sentinel).
Source
Thrown at internal/lockfile/lockfile.go:35
// safeIDChars strips path-traversal chars from app IDs.
var safeIDChars = regexp.MustCompile(`[^a-zA-Z0-9._-]`)
// ErrHeld signals retryable contention; callers errors.Is to distinguish from real failures.
var ErrHeld = errors.New("lockfile: lock already held")
type LockFile struct {
path string
file *os.File
}
func New(path string) *LockFile {
return &LockFile{path: path}
}
// ForSubscribe sanitises appID against path traversal before forming the lock filename.
func ForSubscribe(appID string) (*LockFile, error) {
if appID == "" {
return nil, fmt.Errorf("app ID must not be empty")
}
dir := filepath.Join(core.GetConfigDir(), "locks")
if err := vfs.MkdirAll(dir, 0700); err != nil {
return nil, fmt.Errorf("create lock dir: %w", err)
}
safe := safeIDChars.ReplaceAllString(appID, "_")
name := filepath.Base(fmt.Sprintf("subscribe_%s.lock", safe))
path := filepath.Join(dir, name)
return New(path), nil
}
// TryLock acquires an exclusive non-blocking lock; auto-released on process exit.
func (l *LockFile) TryLock() error {
if l.file != nil {
return fmt.Errorf("%w: %s", ErrHeld, l.path)
}
f, err := vfs.OpenFile(l.path, os.O_CREATE|os.O_RDWR, 0600)
if err != nil {View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Run the CLI auth/config setup so app_id is populated in the profile config.
- Pass the app ID explicitly via the command's flag/argument.
- Check the environment variable feeding the app ID is not unset/empty in your shell or CI.
- Validate app ID non-empty in wrapper scripts before invoking the CLI.
Example fix
// before
lock, err := lockfile.ForSubscribe(appID) // appID == ""
// after
if appID == "" {
return fmt.Errorf("no app configured: run `lark auth` or pass --app-id")
}
lock, err := lockfile.ForSubscribe(appID) Defensive patterns
Strategy: validation
Validate before calling
if appID == "" {
return errors.New("no app configured: run `lark auth` or pass --app-id")
}
lock, err := lockfile.ForSubscribe(appID) Prevention
- Run CLI auth/config setup before event subscribe
- Fail fast on empty app_id in wrapper scripts and CI
- Surface app_id configuration in `--help`/docs so users set it first
When it happens
Trigger: Calling lockfile.ForSubscribe("") — e.g. event subscribe executed before any app credentials were configured, or a config/flag that yields an empty app_id string.
Common situations: User ran `lark event subscribe` without ever running auth/config setup; env var or config file has an empty app_id value; a wrapper script passed an unset variable.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- Invalid column: {column!r}
- Invalid column index: {index}
- anchor outside sheet: {position!r}
- Missing row_count/column_count for sheet {sheet_title(sheet)
- malformed config
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/7e9c204269b04500.
Report an issue: GitHub.