Skip to content

[Regression]: Internal error: step id not found #37147

Closed

Description

Last Good Version

1.54

First Bad Version

1.55

Steps to reproduce

  1. Create a fixture with box: true that calls test.attach():
import { test as base } from '@playwright/test';

const test = base.extend<{ myFixture: void }>({
    myFixture: [async ({}, use, testInfo) => {
        await testInfo.attach('my attachment', {
            body: 'foo',
            contentType: 'text/plain',
        });
        await use();
    }, { box: true }],
});

test('my test', ({ myFixture }) => {});
  1. Run tests npx playwright test

Reproduction repo: https://github.com/vitalets/playwright-issues/tree/error-step-id-not-found

Expected behavior

Attachment is added, no errors in the output.

Actual behavior

Attachment is added, but there is an error in the output Internal error: step id not found:

Running 1 test using 1 worker
Internal error: step id not found: test.attach@34
  1 passed (343ms)

Additional context

No response

Environment

System:
    OS: macOS 14.7.2
    CPU: (10) arm64 Apple M1 Pro
    Memory: 95.75 MB / 16.00 GB
  Binaries:
    Node: 20.18.3 - ~/.nvm/versions/node/v20.18.3/bin/node
    npm: 11.3.0 - ~/.nvm/versions/node/v20.18.3/bin/npm
    pnpm: 10.7.1 - ~/Library/pnpm/pnpm
  Languages:
    Bash: 3.2.57 - /bin/bash
  npmPackages:
    @playwright/test: 1.55 => 1.55.0

Activity

  1. mxschmitt commented on Aug 22, 2025

    @mxschmitt
    Contributor

    I can reproduce.

  2. replete commented on Aug 28, 2025

    @replete

    I don't have a repro for you, but I was getting this [Internal error: step id not found error after upgrading to 1.55.

    It broke tests for me, so I rolled back to 1.54, not having time to deep dive it.

    I wasn't using {box : true} anywhere, so wanted to share my extends file (simplified), in case this helped fix this issue:

    /* eslint-disable no-param-reassign */
    import { test as baseTest, expect as baseExpect } from '@playwright/test';
    // ...
    
    // UnauthenticatedPage:
    /** @returns {import('@playwright/test').Page} */
    const unauthenticatedPage = async ({ page }, use) => {
        // Extended page methods, paired with playwright.extend.d.ts for vscode intellisense:
        page.clearSession = async () => {
            // ...
        };
        page.authenticate = async (user) => {
            // ...
        };
        page.loginPage = () => LoginPage.create(page);
    
        await use(page);
    };
    
    // AuthenticatedPage:
    const createAuthenticatedPage = (user) => async ({ page }, use) => {
        assert(typeof user === 'object', 'user is required');
        const context = page.context();
    
        // authenticate page:
        const authCookies = await getAuthCookies(user);
        if (!authCookies) throw new Error(`Page: Failed to authenticate user ${user.email}`);
        await page.context().addCookies(authCookies);
    
        // handle session expiry:
        context.authRetries = 0;
        context.authRetriesMax = context.authRetriesMax || constants.pageAuthRetriesMax;
        context.isReauthenticating = false;
    
        page.on('response', async (response) => {
            // ...
        });
    
        // Extended page methods, paired with playwright.extend.d.ts for vscode intellisense:
        page.user = user;
        page.clearSession = async () => {
            // ...
        };
        page.reauthenticate = async (forceNewTokens = false) => {
            // ...
        };
        page.startFreshSession = async () => {
            // ...
        };
        page.loginPage = () => LoginPage.create(page);
    
        await use(page);
    };
    
    // CustomTestFixtures:
    export const test = baseTest.extend({
        adminUser: users.admin,
        nonAdminUser: users.nonAdmin,
        // use only one of these per test:
        page: unauthenticatedPage,
        adminPage: createAuthenticatedPage(users.admin),
        nonAdminPage: createAuthenticatedPage(users.nonAdmin),
    });
    
    // CustomMatchers:
    const toHaveLoadedWithoutErrors = async (page) => {
        const hasLoader = await page.locator('.loader').isVisible();
        const hasError = await page.locator('.confirm-description:has-text("error"), .error-message').isVisible();
    
        return {
            pass: !hasLoader && !hasError,
            message: () => (hasLoader ? 'Page still loading' : 'Page has error messages'),
        };
    };
    
    const toBeOneOf = async (received, expected) => {
        const pass = expected.includes(received);
    
        return {
            pass,
            message: () => (pass
                ? `Expected ${received} not to be one of [${expected.join(', ')}]`
                : `Expected ${received} to be one of [${expected.join(', ')}]`),
        };
    };
    
    export const expect = baseExpect.extend({
        toHaveLoadedWithoutErrors,
        toBeOneOf,
    });
    
  3. mxschmitt commented on Aug 28, 2025

    @mxschmitt
    Contributor

    Thanks for the details - could you try npm install -D @playwright/test@beta? There the fix is already included.

  4. Skn0tt commented on Aug 28, 2025

    @Skn0tt
    Contributor

    It broke tests for me, so I rolled back to 1.54, not having time to deep dive it.

    By my understanding of the bug, it's about an unwanted error log, but there's no functionaly impact. So i'm surprised you say it broke tests for you, can you elaborate on that? I want to make sure we're not missing something here.

  5. replete commented on Sep 2, 2025

    @replete

    Thanks for the details - could you try npm install -D @playwright/test@beta? There the fix is already included.

    HI Max Schmitt (@mxschmitt), apologies for the delay - I can confirm that the beta resolves this issue for me, phew!
    Will stay on 1.54 until the next release. Good work, thanks. I'm not sure why exactly it was breaking, but presumably it would be something to do with my use of extends() above.

  6. denyskolopelnyk commented on Sep 30, 2025

    @denyskolopelnyk

    Had been running 1.55.1
    Still got step id not found: fixture@27-89 and browser crash afterwards.
    Had to roll back to 1.54 for stability

  7. Skn0tt commented on Sep 30, 2025

    @Skn0tt
    Contributor

    Hi Denys! We'd like to fix that. Could you file this in a new issue, and provide a reproduction case?

  8. denyskolopelnyk commented on Sep 30, 2025

    @denyskolopelnyk

    I would love to, but the issue occurred in a large test suite in multiple places, never in the same one.
    It did not trigger with the VSCode extension, only with the local console runs
    The only common thing I noticed is that the first test is written twice in the list output: one greyed out and the second one actually passing

  9. replete commented on Sep 30, 2025

    @replete

    I've just pulled 1.55.1 and everything seems to work (like the beta), though I'm seeing Internal error: step id not found: fixture@41 logged regularly. Seem to be regular, so I'll bisect and do some further investigations and report in a relevant open thread:

    Details

    run 1

    Running 380 tests using 8 workers
    ...
      ✓  114 …<redacted>
    Internal error: step id not found: fixture@41
      ...
      ✓  143 …<redacted>
    Internal error: step id not found: fixture@50
     ...
         151 …<redacted>
    Internal error: step id not found: fixture@50
      ...
      ✓  317 …<redacted>
    Internal error: step id not found: fixture@41
      ...
      ✘  333 …<redacted>
    Internal error: step id not found: fixture@50
      ...
      ✓  395 …<redacted>
    Internal error: step id not found: fixture@50
     ...
      ✓  434 …<redacted>
    

    run 2

    Running 380 tests using 8 workers
    ...
      ✓  115 …<redacted>
    Internal error: step id not found: fixture@41
      ✓  141 …<redacted>
    Internal error: step id not found: fixture@50
      ✓  150 …<redacted>
    Internal error: step id not found: fixture@50
      ✓  312 …<redacted>
    Internal error: step id not found: fixture@41
      ✓  333 …<redacted>
    Internal error: step id not found: fixture@50
      ✓  396 …<redacted>
    Internal error: step id not found: fixture@50
    ...
    
  10. seanlafferty-ibm commented on Oct 2, 2025

    @seanlafferty-ibm

    Can confirm we're still seeing this on 1.55.1 too. Totally sporadic and inconsistent so I haven't found a good reproduction. Possible points of interest:

    • we're using custom reporters
    • we have a number of fixtures that depend on fixtures (that depend on fixtures)
    • we're using fullyParallel (with ~300 tests)
    • we're using multiple workers (4)
    • this is happening in CI in the playwright container (1.55.1)
  11. denyskolopelnyk commented on Oct 3, 2025

    @denyskolopelnyk

    Default reporter, 1 worker for serialized tests.
    Thats not it

  12. jonasclaes commented on Oct 7, 2025

    @jonasclaes
    Contributor

    This is currently occurring for our team on v1.56.0. We're not making use of the { box: true }. Is this a regression?

  13. Skn0tt commented on Oct 7, 2025

    @Skn0tt
    Contributor

    It absolutely is. If you could open a separate issue and provide me with a reproduction case, i'd be more than happy to fix it.

  14. jonasclaes commented on Oct 7, 2025

    @jonasclaes
    Contributor
  15. vesper8 commented on Oct 21, 2025

    @vesper8

    I'm still seeing this on playwright@1.56.1-beta-1760662108000

  16. Skn0tt commented on Oct 21, 2025

    @Skn0tt
    Contributor

    Could you try playwright@next?

  17. wannabewayno commented on Oct 28, 2025

    @wannabewayno

    Hey crew, if it helps narrow things down, I also just started seeing the following log repeatidly come up during test execution

    Internal error: step id not found: fixture@23
    

    In my case, I've narrowed it down to the use of screenshot: 'on' in the playwright.config.ts file. With use.screenshot set to 'on' this occurs 100% of the time. With it omitted the error goes away.

    It's worth noting that playing with use.trace and use.video did nothing to affect this behaviour.

    Here is my config file.

    import { defineConfig, devices } from '@playwright/test';
    
    export default defineConfig({
      testDir: './e2e',
      fullyParallel: true,
      forbidOnly: !!process.env.CI,
      retries: process.env.CI ? 2 : 0,
      workers: process.env.CI ? 1 : undefined,
      reporter: [['list'], ['html', { open: 'never' }]],
    
      use: {
        trace: 'retain-on-failure',
        video: 'retain-on-failure',
        screenshot: 'on' // <----------------- This is the culprit
      },
    
      projects: [
        {
          name: 'chromium',
          use: { ...devices['Desktop Chrome'] },
        },
      ],
    
      globalSetup: './globalSetup.ts',
    });
  18. Skn0tt commented on Oct 30, 2025

    @Skn0tt
    Contributor

    Wayne (@wannabewayno) thanks for sharing! I tried reproducing what you're seeing, but it seems to work fine on current main. Going through the code, #37748 should have fixed it for you. If you still experience this issue with the next Playwright minor, or on current nightly Playwright, please file a new issue and i'll take a look.

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

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions