Skip to content

4.x: DataTable fails: Error: Invalid data type. Data accepts either: DataTable || generator || Array || function #5641

Description

@mirao

Found in my production project after the migration from 3.x to 4.x. It works well in 3.x
Maybe the bug has the same reason as #5632 and #5635.

You can reproduce it with the Quickstart project

mirao@rog:~/workspace/my$ codeceptjs run --verbose
***************************************
nodeInfo:  24.16.0
osInfo:  Linux 6.17 Ubuntu 24.04.4 LTS 24.04.4 LTS (Noble Numbat)
cpuInfo:  (16) x64 AMD Ryzen 7 9700X 8-Core Processor
chromeInfo:  149.0.7827.114
edgeInfo:  "N/A"
firefoxInfo:  151.0.3
safariInfo:  N/A
playwrightBrowsers:  "chromium: 149.0.7827.55, firefox: 151.0, webkit: 26.5"
If you need more detailed info, just run this: npx codeceptjs info
***************************************
Error: Invalid data type. Data accepts either: DataTable || generator || Array || function
    at DataTable (/home/mirao/workspace/my/node_modules/codeceptjs/lib/data/context.js:117:10)
    at DataTable (/home/mirao/workspace/my/node_modules/codeceptjs/lib/data/context.js:117:10)
    at DataTable (/home/mirao/workspace/my/tests/My_test.ts:9:1)
    at Object.<anonymous> (/home/mirao/workspace/my/tests/My_test.ts:11:2)
    at Module._compile (node:internal/modules/cjs/loader:1854:14)
    at Object.transformer (/home/mirao/workspace/my/node_modules/tsx/dist/register-BOkp8V6j.cjs:9:3176)
    at Module.load (node:internal/modules/cjs/loader:1577:32)
    at Module._load (node:internal/modules/cjs/loader:1379:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
    at Module.require (node:internal/modules/cjs/loader:1600:12)

Invalid data type. Data accepts either: DataTable || generator || Array || function

Error: 
    at DataTable (/home/mirao/workspace/my/node_modules/codeceptjs/lib/data/context.js:117:10)
    at DataTable (/home/mirao/workspace/my/node_modules/codeceptjs/lib/data/context.js:117:10)
    at DataTable (/home/mirao/workspace/my/tests/My_test.ts:9:1)
    at Object.<anonymous> (/home/mirao/workspace/my/tests/My_test.ts:11:2)
    at Module._compile (node:internal/modules/cjs/loader:1854:14)
    at Object.transformer (/home/mirao/workspace/my/node_modules/tsx/dist/register-BOkp8V6j.cjs:9:3176)
    at Module.load (node:internal/modules/cjs/loader:1577:32)
    at Module._load (node:internal/modules/cjs/loader:1379:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
    at Module.require (node:internal/modules/cjs/loader:1600:12)

tests/My_test.ts:

import { dataTable as DataTable } from 'codeceptjs';

Feature('My');

const cases = new DataTable(['input', 'expected']);
cases.add(['input1', 'expected1']);
cases.add(['input2', 'expected2']);

Data(cases).Scenario('test something',  ({ I, current }) => {
    I.say(`Input: ${current.input}, Expected: ${current.expected}`);
});

codecept.conf.ts:

import { setHeadlessWhen, setCommonPlugins } from '@codeceptjs/configure';
// turn on headless mode when running with HEADLESS=true environment variable
// export HEADLESS=true && npx codeceptjs run
setHeadlessWhen(process.env.HEADLESS);

// enable all common plugins https://github.com/codeceptjs/configure#setcommonplugins
setCommonPlugins();

export const config: CodeceptJS.MainConfig = {
  tests: './tests/*_test.ts',
  output: './output',
  helpers: {
    Playwright: {
      browser: 'chromium',
      url: 'http://localhost',
      show: true
    }
  },
  include: {
    I: './steps_file.ts'
  },
  noGlobals: true,
  plugins: {},
  name: 'my',
  require: ['tsx/cjs']
}

tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022", "DOM"],
    "esModuleInterop": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strictNullChecks": false,
    "types": ["codeceptjs", "node"],
    "declaration": true,
    "skipLibCheck": true
  },
  "exclude": ["node_modules"]
}

Used SW:

  • CodeceptJS 4.0.7

Activity

  1. mirao commented on Jun 16, 2026

    @mirao
    ContributorAuthor

    AI suggests this fix:

    diff --git a/lib/data/context.js b/lib/data/context.js
    index c2e0bc2..b0744d2 100644
    --- a/lib/data/context.js
    +++ b/lib/data/context.js
    @@ -83,7 +83,7 @@ function isTableDataRow(row) {
     }
     
     function detectDataType(dataTable) {
    -  if (dataTable instanceof DataTable) {
    +  if (dataTable instanceof DataTable || (dataTable && Array.isArray(dataTable.rows) && typeof dataTable.add === 'function')) {
         return dataTable.rows
       }
  2. mirao commented on Jun 18, 2026

    @mirao
    ContributorAuthor

    The bug was fixed by #5640 (4.1.0 beta 1), but there is one more issue SyntaxError: Unexpected token (1:3) then. I hit the issue also in 4.0 when I solved #5641 by a patch.

    test:

    const userRoles = new DataTable(["role", "sideBarMenu"]);
    userRoles.add([Role.BLOCK_ADMIN, "blockAdmin"]);
    userRoles.add([Role.SUPER_MENTOR, "superMentor"]);
    userRoles.add([Role.MENTOR, "mentor"]);
    userRoles.add([Role.USER, "teacher"]);
    userRoles.add([Role.SCHOOL_ADMIN, "schoolAdmin"]);
    
    Data(userRoles).Scenario("Set roles to the user", ({ current }) => {
        let entity_type: EntityType;
        let entity_id: string;
    
        switch (current.role) {
            default:
            case Role.USER:
                entity_type = EntityType.TENANT;
                entity_id = String(tenantId);
                break;
    
            case Role.BLOCK_ADMIN:
                entity_type = EntityType.BLOCK;
                entity_id = String(blockId);
                break;
    
            case Role.SUPER_MENTOR:
            case Role.MENTOR:
                entity_type = EntityType.COURSE;
                entity_id = String(course.id);
                break;
    
            case Role.SCHOOL_ADMIN:
                entity_type = EntityType.SCHOOL;
                entity_id = String(school.id);
                break;
        }
        I.setUserRole(
            {
                role: current.role,
                entity_type,
                entity_id,
                user_id: userId,
            },
            adminToken,
        );
    });

    output:

      Course Mentoring disabled: Verify Dashboard tabs | {"role":"ROLE_BLOCK_ADMIN","sideBarMenu":"blockAdmin"}
     › Test Timeout: 600s
     › [Dir] /home/mirao/workspace/codeceptjs/tests/s4w
      Scenario()
    Error in ({current})=>{if([Role.USER,Role.SCHOOL_ADMIN].includes(current.role)){I.click(sideBarMenu.dashboard[current.sideBarMenu].loc);for(const[index,text]of dashboardTabsPage[current.role].entries()){if(current.role===Role.SCHOOL_ADMIN&&(index===2||index===3)){I.dontSeeElement(dashboardTabsPage.tab.at(index+1))}else{I.seeTextEquals(text,dashboardTabsPage.tab.at(index+1))}}}else{I.dontSeeElement(sideBarMenu.dashboard[current.sideBarMenu].loc)}}
    SyntaxError: Unexpected token (1:3)
        [6] Error | TypeError: Cannot read properties of undefined (reading 'role') undefined...
        [6] <teardown>  Stopping recording promises
     › <screenshot> Saving screenshot Course_Mentoring_disabled__Verify_Dashboard_tabs.failed.png
     › [Screenshot] output/Course_Mentoring_disabled__Verify_Dashboard_tabs.failed.png
      ✖ FAILED in 26ms
    
  3. mirao commented on Aug 6, 2026

    @mirao
    ContributorAuthor

    The bug was fixed by #5640 (4.1.0 beta 1), but there is one more issue SyntaxError: Unexpected token (1:3) then.

    Reported as #5679

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions