toeverything/AFFiNE · error · Error

Validation Failed Error\n${message}

Error message

Validation Failed Error\n${message}

What it means

This is the aggregation wrapper used by the ORM's validate() helper: it runs every registered validator (each rule gets a code name like 'DataTypeShouldExactlyMatch' or 'PrimaryKeyShouldExist'), collects failures instead of stopping at the first, and throws one Error whose message lists 'code: stack' per failure under the 'Validation Failed Error' header. The real cause is always the first line after the header.

Source

Thrown at packages/common/infra/src/orm/core/validators/index.ts:16

import { createEntityDataValidators, updateEntityDataValidators } from './data';
import { tableSchemaValidators } from './schema';
import { yjsDataValidators, yjsTableSchemaValidators } from './yjs';

interface ValidationError {
  code: string;
  error: Error;
}

function throwIfError(errors: ValidationError[]) {
  if (errors.length) {
    const message = errors
      .map(({ code, error }) => `${code}: ${error.stack ?? error.message}`)
      .join('\n');

    throw new Error('Validation Failed Error\n' + message);
  }
}

function validate<Validator extends { validate: (...args: any[]) => void }>(
  rules: Record<string, Validator>,
  ...payload: Parameters<Validator['validate']>
) {
  const errors: ValidationError[] = [];

  for (const [code, validator] of Object.entries(rules)) {
    try {
      validator.validate(...payload);
    } catch (e) {
      errors.push({ code, error: e as Error });
    }
  }

  throwIfError(errors);

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Read the first 'CODE: ...stack...' line under the header; fix that validator error (see errors 700–709 for each code).
  2. Fix issues top-to-bottom — each line is an independent validator failure.
  3. If the stack is noisy, match on the code prefix (e.g. /^PrimaryKeyShouldExist:/) to identify which rule fired.
  4. In tests, assert on the presence of the code substring rather than the full message.

Example fix

// before (asserting exact message, brittle with aggregated stacks)
expect(() => create()).toThrow('Field is required');

// after (assert on the validator code embedded in the aggregate)
expect(() => create()).toThrow(/DataTypeShouldExactlyMatch: /);
Defensive patterns

Strategy: try-catch

Validate before calling

// Run your own pre-checks mirroring the validator codes before create/set:
// PrimaryKeyShouldExist, OnlyOnePrimaryKey, PrimaryKeyShouldNotBeOptional,
// DataTypeShouldExactlyMatch (see errors 700-709)

Try / catch

function parseValidation(e: unknown): { code: string; message: string }[] {
  if (!(e instanceof Error) || !e.message.startsWith('Validation Failed Error')) return [];
  return e.message
    .split('\n')
    .slice(1)
    .map(line => { const i = line.indexOf(':'); return { code: line.slice(0, i), message: line.slice(i + 2) }; });
}
try { await db.doc.create(row); } catch (e) {
  for (const v of parseValidation(e)) console.error(v.code, v.message);
}

Prevention

When it happens

Trigger: Any table schema registration or data create/update that trips one or more of the underlying validators (errors 700–709). Multiple simultaneous violations produce multiple lines in one throw.

Common situations: First run after adding a new table with several schema mistakes (no PK, reserved field, bad optional config) — all reported at once; a bad insert that violates both type and required rules; tests that assert on validation behavior and need to parse the aggregated message.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/fc5928e9cf09d940. Report an issue: GitHub.