toeverything/AFFiNE · error · Error

[Table(${tableName})]: Field '${name}' can't be marked prima

Error message

[Table(${tableName})]: Field '${name}' can't be marked primary key and optional with no default value provider at the same time.

What it means

Schema validator PrimaryKeyShouldNotBeOptional rejects a field that is simultaneously a primary key, optional, and has no default provider. Such a field could be absent, which would make the row unaddressable — the ORM cannot look up or update a row with no key, so the configuration is banned up front.

Source

Thrown at packages/common/infra/src/orm/core/validators/schema.ts:35

      for (const name in table) {
        if (table[name].schema.isPrimaryKey) {
          primaryFields.push(name);
        }
      }

      if (primaryFields.length > 1) {
        throw new Error(
          `[Table(${tableName})]: There should be only one field marked as primary key. Found [${primaryFields.join(', ')}].`
        );
      }
    },
  },
  PrimaryKeyShouldNotBeOptional: {
    validate(tableName, table) {
      for (const name in table) {
        const opts = table[name].schema;
        if (opts.isPrimaryKey && opts.optional && !opts.default) {
          throw new Error(
            `[Table(${tableName})]: Field '${name}' can't be marked primary key and optional with no default value provider at the same time.`
          );
        }
      }
    },
  },
};

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Add a default provider so the key is always generated: t.string().primaryKey().default(nanoid).
  2. Or drop .optional() so callers must always supply the key explicitly.
  3. Keep exactly one of: required key, or optional key with default — never optional-without-default.

Example fix

// before
id: t.string().primaryKey().optional()

// after
id: t.string().primaryKey().default(nanoid)
Defensive patterns

Strategy: validation

Validate before calling

for (const [name, f] of Object.entries(fields)) {
  if (f.isPrimaryKey && f.optional && !f.default) {
    throw new Error(`field '${name}': primary key must be required or have a default`);
  }
}

Prevention

When it happens

Trigger: Declaring id: t.string().primaryKey().optional() with no .default(...); marking a key optional to make inserts 'easier'; refactoring a previously-required key into optional during a migration.

Common situations: Wanting auto-generated ids but marking optional instead of providing a default generator; inconsistency introduced when copying a field definition chain and dropping the default part.

Related errors


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