lbjlaq/Antigravity-Manager · error · Error

accounts.add.oauth.error_no_url

Error message

accounts.add.oauth.error_no_url

What it means

handleOAuthWeb throws this when prepare_oauth_url returns no usable URL (neither a plain string nor an object with a truthy url property). It signals that the backend could not build the OAuth authorization URL.

Solutions

  1. Check backend OAuth client configuration (client id/secret, auth endpoint) is set before opening the dialog
  2. Inspect what prepare_oauth_url actually returns (log res) and handle both string and {url} shapes
  3. Surface the backend error message instead of the generic no-url error

Example fix

// before
const url = typeof res === 'string' ? res : res.url;
if (!url) {
    throw new Error(t('accounts.add.oauth.error_no_url', 'OAuth URLを取得できませんでした'));
}
// after
const url = typeof res === 'string' ? res : res?.url;
if (!url) {
    throw new Error(res?.error ?? t('accounts.add.oauth.error_no_url', 'OAuth URLを取得できませんでした'));
}
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await invoke('prepare_oauth_url'); const url = typeof res === 'string' ? res : res?.url; if (!url) return showError('no OAuth URL');

Type guard

const hasUrl = (r: unknown): r is { url: string } => typeof r === 'object' && r !== null && typeof (r as any).url === 'string' && (r as any).url.length > 0;

Try / catch

try { await handleOAuthWeb(); } catch (e) { setDialogError(e?.message || t('accounts.add.oauth.error_no_url')); }

Prevention

When it happens

Trigger: invoke('prepare_oauth_url') resolves to null/undefined/empty string, or to an object without a url field — typically because the backend OAuth client config is missing or get_auth_url panicked/failed.

Common situations: OAuth client credentials not configured on the backend; backend returned an error object the frontend misreads; the active OAuth client config is invalid.

Related errors


AI-assisted analysis of lbjlaq/Antigravity-Manager@90a2b6b207 (2026-09-19). Data as JSON: /api/errors/3fda3dc3ffe98f0d. Report an issue: GitHub.

Appendix: source

Thrown at src/components/accounts/AddAccountDialog.tsx:287

            // 不自动关闭,让用户看到结果
        } else {
            // 全部失败
            setStatus('error');
            setMessage(t('accounts.add.token.batch_fail'));
        }
    };

    const handleOAuthWeb = async () => {
        try {
            setStatus('loading');
            setMessage(t('accounts.add.oauth.btn_start') + '...');

            // 1. 获取 URL (指向 /auth/callback)
            const res = await invoke<any>('prepare_oauth_url');
            const url = typeof res === 'string' ? res : res.url;

            if (!url) {
                throw new Error(t('accounts.add.oauth.error_no_url', 'OAuth URLを取得できませんでした'));
            }

            setOauthUrl(url); // 确保链接在 UI 中可见,方便用户手动复制

            // 2. 打开新标签页 (响应用户反馈:Web 端直接使用新标签体验更好)
            const popup = window.open(url, '_blank');

            if (!popup) {
                setStatus('error');
                setMessage(t('accounts.add.oauth.popup_blocked', 'ポップアップがブロックされました'));
                return;
            }

            // 3. 监听消息
            const handleMessage = async (event: MessageEvent) => {
                // 安全检查: 如果定义了 ORIGIN 校验更好,这里暂时检查 data type
                if (event.data?.type === 'oauth-success') {
                    popup.close();

View on GitHub (pinned to 90a2b6b207)