larksuite/cli · error

keychain access blocked

Error message

keychain access blocked

What it means

errKeychainBlocked is returned when the OS keychain is reachable but denies access — a sandbox restriction, a user-denied permission prompt, or the 5-second getMasterKey timeout caused by an ignored permission dialog. It is deliberately distinct from errNotInitialized (entry genuinely absent) so wrapError's hint can tell users the difference and suggest permission fixes rather than reconfiguration.

Source

Thrown at internal/keychain/keychain_darwin.go:50

const ivBytes = 12

// tagBytes is the authentication tag size produced by AES-GCM.
const tagBytes = 16

// fileMasterKeyName is the local fallback master key file name.
const fileMasterKeyName = "master.key.file"

// keyringGet is overridden in tests to simulate system keychain reads.
var keyringGet = keyring.Get

// keyringSet is overridden in tests to simulate system keychain writes.
var keyringSet = keyring.Set

// errKeychainBlocked is returned when the OS Keychain is reachable but
// denies access — sandbox restriction, user-denied prompt, or a 5-second
// timeout (typically caused by an ignored permission dialog). Distinct
// from errNotInitialized (master key entry genuinely absent).
var errKeychainBlocked = errors.New("keychain access blocked")

// StorageDir returns the storage directory for a given service name on macOS.
func StorageDir(service string) string {
	home, err := vfs.UserHomeDir()
	if err != nil || home == "" {
		return filepath.Join(".lark-cli", "keychain", service)
	}
	return filepath.Join(home, "Library", "Application Support", service)
}

var safeFileNameRe = regexp.MustCompile(`[^a-zA-Z0-9._-]`)

// safeFileName sanitizes an account name to be used as a safe file name.
func safeFileName(account string) string {
	return safeFileNameRe.ReplaceAllString(account, "_") + ".enc"
}

// getMasterKey retrieves the master key from the system keychain.

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Re-run the command and click 'Always Allow' on the macOS keychain permission dialog
  2. Run the CLI outside the sandbox/IDE sandbox (grant the host app keychain access in System Settings)
  3. If in CI, pre-unlock the keychain / grant the runner access, or configure a non-keychain storage path
Defensive patterns

Strategy: retry

Validate before calling

// probe keychain access early with a cheap Get on a known service
if _, err := kc.Get(service, account); err != nil && errors.Is(err, errKeychainBlocked) {
    // surface permission guidance before the real operation
}

Type guard

func isKeychainBlocked(err error) bool { return errors.Is(err, errKeychainBlocked) }

Try / catch

err := kc.Set(service, account, secret)
if errors.Is(err, errKeychainBlocked) {
    // retry once after user grants keychain access, else print the sandbox/permission hint
}

Prevention

When it happens

Trigger: Calling keychain operations on macOS where the security prompt is denied or ignored (ctx timeout at keychain_darwin.go:126), or keyring.Get returns an error other than ErrNotFound (keychain_darwin.go:94).

Common situations: Running lark-cli inside an IDE terminal or CI sandbox without keychain entitlements; the macOS 'allow access' dialog appearing off-screen or behind other windows and timing out; corporate MDM policies blocking keychain access.

Related errors


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