jquense/yup · error · Error

Validation test of type: "${ctx.type}" returned a Promise du

Error message

Validation test of type: "${ctx.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned

What it means

During synchronous validation (validateSync / sync option), each test function must return a boolean synchronously. If a test returns a Promise (async test), this Error is thrown to warn that the test result will arrive after validateSync has already returned, i.e. its outcome is silently ignored.

Source

Thrown at src/util/createValidation.ts:155

    };

    const handleError = (err: any) => {
      if (ValidationError.isError(err)) invalid(err);
      else panic(err);
    };

    const shouldSkip = skipAbsent && isAbsent(value);

    if (shouldSkip) {
      return handleResult(true);
    }

    let result: ReturnType<TestFunction>;
    try {
      result = test.call(ctx, value, ctx);
      if (typeof (result as any)?.then === 'function') {
        if (options.sync) {
          throw new Error(
            `Validation test of type: "${ctx.type}" returned a Promise during a synchronous validate. ` +
              `This test will finish after the validate call has returned`,
          );
        }
        return Promise.resolve(result).then(handleResult, handleError);
      }
    } catch (err: any) {
      handleError(err);
      return;
    }

    handleResult(result);
  }

  validate.OPTIONS = config;

  return validate;
}

View on GitHub (pinned to ff31eee8a2)

Solutions

  1. Use await schema.validate() instead of validateSync() when tests are async
  2. Make the test function synchronous if sync validation is required
  3. Pre-compute async data before validation and pass it in so tests stay sync
  4. Remove the sync flag and switch the whole flow to async validation

Example fix

// before
schema.validateSync(value); // test returns a Promise -> throws
// after
await schema.validate(value);
Defensive patterns

Strategy: validation

Validate before calling

const hasAsyncTest = myTests.some(t => t.constructor.name === 'AsyncFunction');
if (hasAsyncTest) await schema.validate(value); else value = schema.validateSync(value);

Type guard

function isSyncTestResult(r: unknown): r is boolean {
  return typeof r === 'boolean';
}
// or detect async fns up front:
const isAsyncFn = (f: Function) => f.constructor.name === 'AsyncFunction';

Try / catch

try { return schema.validateSync(v); } catch (e) { if (/returned a Promise during a synchronous/.test(e.message)) return await schema.validate(v); throw e; }

Prevention

When it happens

Trigger: Passing an async test (async value => {...} or a function returning a promise, e.g. from an async uniqueness check) to a schema validated with validateSync() or { sync: true }.

Common situations: Reusing the same schema with async DB-backed tests for both async and sync validation; using validateSync in a server handler while a test calls fetch/async storage.

Related errors


AI-assisted analysis of jquense/yup@ff31eee8a2 (2026-08-31). Data as JSON: /api/errors/1be3cbf40ccb4d27. Report an issue: GitHub.