CherryHQ/cherry-studio · info · Error
Registration polling aborted
Error message
Registration polling aborted
What it means
Thrown by registrationPoll() when the passed AbortSignal is aborted before the deadline. The poll loop checks options.signal?.aborted at the top of each iteration and throws this constant message so callers can distinguish a user/system cancellation from a real failure.
Source
Thrown at src/main/ai/channels/adapters/feishu/FeishuAppRegistration.ts:96
deviceCode,
verificationUri,
interval: (res.interval as number) ?? 5,
expiresIn: (res.expires_in as number) ?? 600
}
}
export async function registrationPoll(
domain: FeishuDomain,
deviceCode: string,
options: { interval: number; expiresIn: number; signal?: AbortSignal }
): Promise<RegistrationResult> {
const baseUrl = BASE_URLS[domain]
const deadline = Date.now() + options.expiresIn * 1000
let interval = options.interval * 1000
while (Date.now() < deadline) {
if (options.signal?.aborted) {
throw new Error('Registration polling aborted')
}
await delay(interval, { signal: options.signal })
const res = await postRegistration(baseUrl, {
action: 'poll',
device_code: deviceCode
})
// Success: got credentials
if (res.client_id && res.client_secret) {
const userInfo = res.user_info as Record<string, string> | undefined
logger.info('Feishu app registration succeeded')
return {
appId: res.client_id as string,
appSecret: res.client_secret as string,
openId: userInfo?.open_id
}View on GitHub (pinned to 726446b54c)
Solutions
- Treat this error as benign cancellation, not a fault — catch it and surface 'cancelled' to the UI.
- Only abort the signal on explicit user cancellation or teardown; do not reuse general-purpose signals.
- Ensure abort() is called exactly once when the registration screen unmounts.
Defensive patterns
Strategy: try-catch
Validate before calling
// Only abort the signal on real cancellation/teardown. const controller = new AbortController() onUserCancel(() => controller.abort()) onTeardown(() => controller.abort())
Type guard
function isRegistrationAborted(e: unknown): e is Error {
return e instanceof Error && e.message === 'Registration polling aborted'
} Try / catch
try {
await registrationPoll(domain, deviceCode, { interval, expiresIn, signal: controller.signal })
} catch (e) {
if (isRegistrationAborted(e)) { logger.info('registration cancelled by user/teardown'); return }
throw e
} Prevention
- Treat 'Registration polling aborted' as benign cancellation, not a fault.
- Abort exactly once on unmount/teardown; do not reuse the signal.
- Distinguish cancellation from real errors in the UI.
When it happens
Trigger: Caller passes an AbortSignal that fires (abort()) while registrationPoll is looping between deadline checks; the next iteration observes signal.aborted and throws.
Common situations: User cancelled the QR-code registration flow from the UI, the app is shutting down and aborted in-flight polls, or a navigation/unmount aborted the controller.
Related errors
- Login cancelled
- Feishu WebSocket connection failed: ${error instanceof Error
- Client is not connected
- Invalid JSON from Feishu registration API: ${text.slice(0, 2
- Feishu registration begin failed: ${JSON.stringify(res)}
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/0e0b0f2a6a85b0db.
Report an issue: GitHub.