toeverything/AFFiNE · error
Invalid authentication url
Error message
Invalid authentication url
What it means
The iOS app's deep-link handler only processes URLs whose hostname is 'authentication'; it then requires a method query param of exactly 'magic-link' or 'oauth' and a truthy JSON-parsed payload param. Missing method, an unknown method, or a payload that parses to a falsy value throws 'Invalid authentication url' (app.tsx:724). A malformed payload param throws a SyntaxError from JSON.parse even earlier, at line 720.
Source
Thrown at packages/frontend/apps/ios/src/app.tsx:748
notify.error({
title: I18n['com.affine.auth.toast.title.failed'](),
message: getErrorMessage(error, fallback),
});
};
const handleAuthenticationCallback = async (url: string) => {
const urlObj = new URL(url);
if (urlObj.hostname !== 'authentication') {
return;
}
const method = urlObj.searchParams.get('method');
const payload = JSON.parse(urlObj.searchParams.get('payload') ?? 'false');
const serverBaseUrl = urlObj.searchParams.get('server');
if (!method || (method !== 'magic-link' && method !== 'oauth') || !payload) {
throw new Error('Invalid authentication url');
}
let authService = frameworkProvider
.get(DefaultServerService)
.server.scope.get(AuthService);
if (serverBaseUrl) {
const serversService = frameworkProvider.get(ServersService);
const server = serversService.getServerByBaseUrl(serverBaseUrl);
if (!server) {
throw new Error(
`Authentication callback server not found: ${serverBaseUrl}`
);
}
authService = server.scope.get(AuthService);
}
if (method === 'oauth') {View on GitHub (pinned to b6de0ad51b)
Solutions
- Capture the exact incoming URL and inspect its query params (method, payload, server) before anything else
- Emit links in the canonical form: <scheme>://authentication?method=oauth|magic-link&payload=<encodeURIComponent(JSON)>&server=<baseUrl>
- Make sure payload parses to a truthy JSON object ({code,state,provider} for oauth; {email,token} for magic-link)
- Regenerate the callback with the current auth flow (updated app version) rather than a saved link
Example fix
// before: unencoded payload breaks the query string
const url = `affine://authentication?method=oauth&payload=${JSON.stringify(p)}`;
// after: encode every parameter value
const url = `affine://authentication?method=oauth&payload=${encodeURIComponent(JSON.stringify(p))}`; Defensive patterns
Strategy: validation
Validate before calling
// validate the callback URL before acting on it
const u = new URL(url);
if (u.hostname !== 'authentication') return;
const method = u.searchParams.get('method');
let payload: unknown;
try {
payload = JSON.parse(u.searchParams.get('payload') ?? 'null');
} catch {
return notifyInvalidLink();
}
if (method !== 'magic-link' && method !== 'oauth') return notifyInvalidLink();
if (!payload || typeof payload !== 'object') return notifyInvalidLink();
await handleAuthenticationCallback(url); Type guard
const isAuthCallbackUrl = (url: string): boolean => {
try {
const u = new URL(url);
if (u.hostname !== 'authentication') return false;
const method = u.searchParams.get('method');
if (method !== 'magic-link' && method !== 'oauth') return false;
const p = u.searchParams.get('payload');
if (!p) return false;
const payload = JSON.parse(p);
return !!payload && typeof payload === 'object';
} catch {
return false;
}
}; Try / catch
// already the app's pattern: notify, never crash the listener handleAuthenticationCallback(url).catch(error => notifyAuthenticationError(error, 'Failed to handle authentication callback') );
Prevention
- Always encodeURIComponent the payload JSON when constructing callback URLs
- Keep one link-builder function so method/payload/server params are always consistent
- Log the raw deep link on failure — the query string is the whole diagnosis
When it happens
Trigger: A callback URL like affine://authentication?foo=1 (no method), ...?method=saml (unsupported), ...?payload=false / payload=null, or payload absent. Also any payload that is valid JSON but evaluates falsy.
Common situations: Hand-built or truncated deep links during testing; URL-encoding bugs where the payload param is dropped or cut at an unencoded character (e.g. '{' or '&'); stale links generated by an older app/auth-flow version; custom-scheme routing mangling query strings.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Authentication callback server not found: ${serverBaseUrl}
- action_forbidden
- wrong_sign_in_credentials
- invalid_auth_state
- invalid_email_token
AI-assisted analysis of toeverything/AFFiNE@b6de0ad51b (2026-08-21).
Data as JSON: /api/errors/9580f299f94cfc58.
Report an issue: GitHub.