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

  1. Update the client to a version that satisfies the server's requiredVersion range.
  2. If you control the server, align config.client.versionControl.requiredVersion with the deployed client range.
  3. Ensure the client sends the correct version header on every request/socket handshake.
  4. 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

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


AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12). Data as JSON: /api/errors/9070d858cf2b5a4e. Report an issue: GitHub.