toeverything/AFFiNE · error · UnsupportedClientVersion
unsupported_client_version
unsupported_client_version
Error message
Unsupported client with version [${clientVersion}], required version is [${requiredVersion}]. What it means
Thrown by VersionService.checkVersion() when the client version is not allowed. There are three trigger paths: (a) on the canary namespace, a canary-style client version older than ~2 months is rejected; (b) the client version does not satisfy the configured requiredVersion range; (c) the client version does not satisfy the hard floor '>=0.25.0'. A missing/invalid clientVersion is treated as a failure against any active range.
Source
Thrown at packages/backend/server/src/core/version/service.ts:28
@Injectable()
export class VersionService {
private readonly logger = new Logger(VersionService.name);
private static readonly HARD_REQUIRED_VERSION = '>=0.25.0';
private static readonly CANARY_REQUIRED_VERSION = 'canary (within 2 months)';
constructor(private readonly config: Config) {}
async checkVersion(clientVersion?: string) {
const requiredVersion = this.config.client.versionControl.requiredVersion;
if (clientVersion && env.namespaces.canary) {
const canaryCheck = checkCanaryDateClientVersion(clientVersion);
if (canaryCheck.matched) {
if (canaryCheck.allowed) {
return true;
}
throw new UnsupportedClientVersion({
clientVersion,
requiredVersion: VersionService.CANARY_REQUIRED_VERSION,
});
}
}
const hardRange = await this.getVersionRange(
VersionService.HARD_REQUIRED_VERSION
);
const configRange = await this.getVersionRange(requiredVersion);
if (
configRange &&
(!clientVersion ||
!semver.satisfies(clientVersion, configRange, {
includePrerelease: true,
}))
) {View on GitHub (pinned to 26c515e050)
Solutions
- Update the client to a version that satisfies the server's requiredVersion range.
- If you control the server, align config.client.versionControl.requiredVersion with the deployed client range.
- Ensure the client sends the correct version header on every request/socket handshake.
- For canary builds, refresh the build within the 2-month window.
Example fix
// before — server requires >=0.25.0 but client is 0.20.1
headers: { 'x-affine-version': '0.20.1' }
// after
headers: { 'x-affine-version': '0.26.0' } Defensive patterns
Strategy: validation
Validate before calling
import semver from 'semver';
const clientVersion = getAppVersion();
if (!semver.satisfies(clientVersion, REQUIRED_RANGE)) { promptUpgrade(); return; } Type guard
function isClientVersionAllowed(version: string | undefined, range: string): boolean {
return Boolean(version) && semver.satisfies(version, range, { includePrerelease: true });
} Try / catch
try {
await connect();
} catch (e) {
if (e?.code === 'unsupported_client_version') { forceUpgrade(); return; }
throw e;
} Prevention
- Always send the correct version header on requests and socket handshakes.
- Prompt in-app upgrades when the client detects it is below the server's required range.
- Keep config.client.versionControl.requiredVersion aligned with the deployed client range.
- Refresh canary builds within the 2-month window.
When it happens
Trigger: Client connects with an x-affine-version (or canary version) that is too old relative to the server's HARD_REQUIRED_VERSION, the config requiredVersion, or (for canary builds) older than the 2-month canary window. Also fires when the version header is absent and a range is active.
Common situations: User running an outdated client against a newer server; server upgraded its requiredVersion config without a matching client release; canary build not updated within 2 months; client not sending the version header at all.
Related errors
- unsupported_client_version
- unsupported_client_version
- ErrorCode.ValueNotExists
- Invalid config for module [${module}] with key [${key}] Valu
- Invalid `server.externalUrl` configured. It must be a valid
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/9070d858cf2b5a4e.
Report an issue: GitHub.