medusajs/medusa · warning

Some tables still contain data after truncate: ${tableList}

Error message

Some tables still contain data after truncate: ${tableList}

What it means

medusa-test-utils' DB test utility truncates all tables between tests and then verifies they are empty by counting rows per table. If any table still has rows (FK-restricted truncate, tables not in the truncate list, or async inserts racing the check), it lists the offending tables with counts and returns false.

Source

Thrown at packages/medusa-test-utils/src/database.ts:397

          const nonEmptyTables = counts.filter(
            (row: { table_name: string; count: string }) =>
              parseInt(row.count) > 0
          )

          if (nonEmptyTables.length === 0) {
            return true
          }

          if (retry < maxRetries - 1) {
            await new Promise((resolve) => setTimeout(resolve, 100))
          } else {
            const tableList = nonEmptyTables
              .map(
                (t: { table_name: string; count: string }) =>
                  `${t.table_name}(${t.count})`
              )
              .join(", ")
            logger.warn(
              `Some tables still contain data after truncate: ${tableList}`
            )
          }
        }
        return false
      }

      await verifyEmpty()
    } catch (error) {
      logger.error("Error during database teardown:", error)
      throw error
    }
  },

  shutdown: async function (dbName: string) {
    try {
      await closePgConnection(this.pgConnection_)
      await unregisterFrameworkPgConnection(this.pgConnection_)

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Stop background workers/jobs and in-flight event handling before truncating (await pending async work in test teardown)
  2. Add the listed tables to the truncate list or ensure TRUNCATE ... CASCADE is used
  3. Check for a new migration whose table isn't included by the utils' table discovery, and update the helper
  4. Debug which test leaves rows: run suites in isolation and watch when the listed tables first stay non-empty
Defensive patterns

Strategy: validation

Validate before calling

const nonEmpty = await util.verifyEmpty()
if (!nonEmpty) {
  await util.truncate() // or fail the test to surface pollution
}

Prevention

When it happens

Trigger: Calling dbTestUtil.truncate() / verifyEmpty after tests where cascade truncation failed (e.g. postgres TRUNCATE without CASCADE on FK-connected tables) or background workers/jobs inserted rows between truncate and verification.

Common situations: Test pollution causing flaky dependent tests; a table added by a new migration that the truncate helper doesn't cover; scheduled jobs or event subscribers still running and writing rows during teardown.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/2273e5bd667e831b. Report an issue: GitHub.