{"record":{"id":"2273e5bd667e831b","repo":"medusajs/medusa","slug":"some-tables-still-contain-data-after-truncate-t","errorCode":null,"errorMessage":"Some tables still contain data after truncate: ${tableList}","messagePattern":"Some tables still contain data after truncate: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/medusa-test-utils/src/database.ts","lineNumber":397,"sourceCode":"          const nonEmptyTables = counts.filter(\n            (row: { table_name: string; count: string }) =>\n              parseInt(row.count) > 0\n          )\n\n          if (nonEmptyTables.length === 0) {\n            return true\n          }\n\n          if (retry < maxRetries - 1) {\n            await new Promise((resolve) => setTimeout(resolve, 100))\n          } else {\n            const tableList = nonEmptyTables\n              .map(\n                (t: { table_name: string; count: string }) =>\n                  `${t.table_name}(${t.count})`\n              )\n              .join(\", \")\n            logger.warn(\n              `Some tables still contain data after truncate: ${tableList}`\n            )\n          }\n        }\n        return false\n      }\n\n      await verifyEmpty()\n    } catch (error) {\n      logger.error(\"Error during database teardown:\", error)\n      throw error\n    }\n  },\n\n  shutdown: async function (dbName: string) {\n    try {\n      await closePgConnection(this.pgConnection_)\n      await unregisterFrameworkPgConnection(this.pgConnection_)","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/medusa-test-utils/src/database.ts#L379-L415","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Stop background workers/jobs and in-flight event handling before truncating (await pending async work in test teardown)","Add the listed tables to the truncate list or ensure TRUNCATE ... CASCADE is used","Check for a new migration whose table isn't included by the utils' table discovery, and update the helper","Debug which test leaves rows: run suites in isolation and watch when the listed tables first stay non-empty"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const nonEmpty = await util.verifyEmpty()\nif (!nonEmpty) {\n  await util.truncate() // or fail the test to surface pollution\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Await all async work (workers, subscribers) before teardown truncation","Use CASCADE truncation and keep the table list updated with migrations","Fail fast on test-db pollution instead of tolerating leftovers"],"tags":["testing","test-utils","database","truncate"],"backgroundTag":"test-db-pollution","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}