BaseEntity.Validate() accepts an empty string for a NOT NULL string column, so a required field the form paints red still saves

Open Beginner friendly
#4,359 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
backend

Research direction

Start in packages/MJCore/src/generic/baseEntity.ts at EntityField.Validate(), then inspect MjFormFieldComponent.IsRequiredEmpty to compare the existing required-field rules. Add tests under packages/MJCore/src/tests/ for empty and whitespace-only values on non-null string fields, while confirming nullable empty strings still pass. Done means validation reports the field name and blocks the save consistently with the form.

Written by the indexing model from the issue text.

Description

Summary

EntityField.Validate() treats an empty string as satisfying a NOT NULL string column, so a required field that the form paints red as "required and empty" still saves — with '' persisted in the column. The UI and the save disagree about the same value.

Repro

MJ next @ 6ac6bcc5ca (6.1.0-edge), Explorer, any entity with a NOT NULL nvarchar column that has no default. Used MJ: AI Agent Request TypesName (nvarchar(200), AllowsNull = 0, no default).

  1. Open an existing record, click Edit.
  2. Clear Name. The field paints its underline red (mj-forms-field--required-empty) — the form clearly considers it invalid.
  3. Click Save.

Expected: the save is refused with a field-named validation failure, the same way a null would be.
Actual: "Record saved successfully". The row now has Name = '' (LEN(Name) = 0, verified in SQL). Observed live on 2026-09-10 while validating #4355; the record was restored by hand.

Root cause

packages/MJCore/src/generic/baseEntity.ts, EntityField.Validate(), nullability rung:

if (!ef.AllowsNull && (this.Value === null || this.Value === undefined)) {

Only null / undefined fail. '' passes, and SQL Server accepts '' in a NOT NULL column, so nothing downstream catches it either.

The form field takes the opposite view — MjFormFieldComponent.IsRequiredEmpty:

return val === null || val === undefined || val === '';

So the two rules that are supposed to describe the same thing ("this required field has no value") disagree exactly on ''. The new section indicators from #4355 mirror the field rule, so they also flag '' as invalid before save — consistent with the field, inconsistent with Validate() until this is settled.

Proposed fix

Treat an empty (or whitespace-only) string as "missing" for AllowsNull === false string columns in EntityField.Validate():

const missing = this.Value === null || this.Value === undefined
  || (ef.TSType === EntityFieldTSType.String && typeof this.Value === 'string' && this.Value.trim().length === 0);
if (!ef.AllowsNull && missing) { ... }

keeping the existing default-value / new-record carve-out as is. That matches what a user means by a required text field, and it is what the form already promises visually.

If there are entities where an empty string in a NOT NULL column is legitimately meaningful, the alternative is the other direction — stop IsRequiredEmpty from painting '' red — but that seems the less useful contract. Either way the two should agree.

Notes

  • Not a regression: the nullability rung has read this way for a long time; #4355 just made the disagreement visible at the section level as well as the field level.
  • Test to add alongside the fix: packages/MJCore/src/__tests__/ — a NOT NULL string field set to '' and to ' ' on an existing record fails Validate() with Source = the field name; a nullable string field set to '' still passes.
Dominant language
TSQL
Stars
29
Forks
6
Avg merge
1d 1h
Merged PRs (30d)
295

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from MemberJunction/MJ

All issues in MemberJunction/MJ

Similar issues

More Backend & API Design issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.