{"record":{"id":"c582dfa714acfa4f","repo":"facebook/react","slug":"log-is-not-empty-assert-on-the-log-of-yielded-val","errorCode":null,"errorMessage":"Log is not empty. Assert on the log of yielded values before flushing additional work.","messagePattern":"Log is not empty\\. Assert on the log of yielded values before flushing additional work\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/scheduler/src/forks/SchedulerMock.js","lineNumber":612,"sourceCode":"      isFlushing = false;\n    }\n  } else {\n    return false;\n  }\n}\n\nfunction unstable_clearLog(): Array<mixed> {\n  if (yieldedValues === null) {\n    return [];\n  }\n  const values = yieldedValues;\n  yieldedValues = null;\n  return values;\n}\n\nfunction unstable_flushAll(): void {\n  if (yieldedValues !== null) {\n    throw new Error(\n      'Log is not empty. Assert on the log of yielded values before ' +\n        'flushing additional work.',\n    );\n  }\n  unstable_flushAllWithoutAsserting();\n  if (yieldedValues !== null) {\n    throw new Error(\n      'While flushing work, something yielded a value. Use an ' +\n        'assertion helper to assert on the log of yielded values, e.g. ' +\n        'expect(Scheduler).toFlushAndYield([...])',\n    );\n  }\n}\n\nfunction log(value: mixed): void {\n  // eslint-disable-next-line react-internal/no-production-logging\n  if (console.log.name === 'disabledLog' || disableYieldValue) {\n    // If console.log has been patched, we assume we're in render","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/scheduler/src/forks/SchedulerMock.js#L594-L630","documentation":"unstable_flushAll() is the strict assertion-path flush behind expect(Scheduler).toFlushAndYield([...]): before doing any work it requires the mock's yielded-value log (yieldedValues, populated by Scheduler.log()) to be empty. If a previous flush or setup left values unasserted, it throws 'Log is not empty. Assert on the log of yielded values before flushing additional work.' and performs no flush — the mock forces you to consume logged values between flushes.","triggerScenarios":"A prior flush helper (e.g. unstable_flushAllWithoutAsserting, or an assertion whose expectation was skipped) executed tasks that called Scheduler.log(value) and nothing consumed them; the test then calls Scheduler.unstable_flushAll() or toFlushAndYield again with a non-empty log.","commonSituations":"Mixing strict and non-strict flush helpers in one test; log leakage between tests because the mock was not reset in beforeEach; conditional logging branches that produce values the expectation did not cover.","solutions":["Assert the pending values first with expect(Scheduler).toFlushAndYield([...]) (or toFlushAndYieldThrough([...])) so the log is consumed.","If you genuinely do not care about the stale values, drain them with Scheduler.unstable_clearLog() before the strict flush.","Add Scheduler.unstable_reset() in beforeEach to stop tasks and log leaking between tests.","Standardize on one assertion helper per flush instead of flushing twice in a row."],"exampleFix":"// before\nScheduler.scheduleCallback(NormalPriority, () => Scheduler.log('a'));\nScheduler.unstable_flushAllWithoutAsserting(); // log now holds ['a']\nScheduler.unstable_flushAll(); // throws: Log is not empty\n\n// after\nScheduler.scheduleCallback(NormalPriority, () => Scheduler.log('a'));\nexpect(Scheduler).toFlushAndYield(['a']); // asserts and clears the log\nexpect(Scheduler).toFlushAndYield([]); // now safe to flush again","handlingStrategy":"validation","validationCode":"// Drain (and optionally assert) pending values before a strict flush.\nconst pending = Scheduler.unstable_clearLog(); // returns and clears the log\nif (pending.length > 0) {\n  // assert on `pending`, or deliberately discard it\n}\nScheduler.unstable_flushAll(); // now safe","typeGuard":null,"tryCatchPattern":"try {\n  Scheduler.unstable_flushAll();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Log is not empty')) {\n    Scheduler.unstable_clearLog();\n    Scheduler.unstable_flushAll(); // retry with a clean log\n  } else {\n    throw e;\n  }\n}","preventionTips":["Assert yielded values after every flush that produces them (toFlushAndYield / toFlushAndYieldThrough).","Reset the mock (Scheduler.unstable_reset()) in beforeEach to prevent log leakage between tests.","Pick one flush style per test — do not mix strict and non-asserting helpers without asserting in between."],"tags":["scheduler","testing","mock","assertions"],"backgroundTag":"unasserted-yielded-log","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}