Cypress: `Cannot read property 'body' of null` error on cy.wait-ing for a request

Created on 6 Aug 2019  路  12Comments  路  Source: cypress-io/cypress

Current behavior:

When waiting for a route/response, the first request is cancelled (unfortunately no idea why), and the second request (which contains the body, has status 200, etc.) is missed by the wait.
This leads to an error: Cannot read property 'body' of null.

Please see the video here: https://dashboard.cypress.io/#/projects/5yp4q1/runs/443/failures/82eb323a-53a8-46a2-86e6-d9a64f4caa87
Here's a screenshot with the error: 0000000391


Here's the relevant piece of code

function performDocumentViewAction(windowId, documentViewAction, documentIdAliasName) {
  cy.server();
  const layoutAliasName = `visitWindow-layout-${new Date().getTime()}`;
  cy.route('GET', new RegExp(`/rest/api/window/${windowId}/layout`)).as(layoutAliasName);
  const dataAliasName = `visitWindow-data-${new Date().getTime()}`;
  cy.route('GET', new RegExp(`/rest/api/window/${windowId}/[0-9]+$`)).as(dataAliasName);

  documentViewAction();
  cy.wait(`@${layoutAliasName}`, {
    requestTimeout: 20000,
    responseTimeout: 20000,
  })
    .wait(`@${dataAliasName}`, {
      requestTimeout: 20000,
      responseTimeout: 20000,
    })
    .then(xhr => {
      return { documentId: xhr.response.body[0].id };  // here we get the null
    })
    .as(documentIdAliasName);
}

It can be read here: https://github.com/metasfresh/metasfresh-e2e/blob/master/cypress/support/commands/general.js#L251.


After much testing locally i have managed to repro this once, but locally i see no cancelled request, yet the null error still appears:
image


Here's the code i have used locally (the only difference is the logging and having to use cy.wrap)

function performDocumentViewAction(windowId, documentViewAction, documentIdAliasName) {
  cy.server();
  const layoutAliasName = `visitWindow-layout-${new Date().getTime()}`;
  cy.route('GET', new RegExp(`/rest/api/window/${windowId}/layout`)).as(layoutAliasName);
  const dataAliasName = `visitWindow-data-${new Date().getTime()}`;
  cy.route('GET', new RegExp(`/rest/api/window/${windowId}/[0-9]+$`)).as(dataAliasName);

  documentViewAction();
  cy.wait(`@${layoutAliasName}`, {
    requestTimeout: 20000,
    responseTimeout: 20000,
  })
    .wait(`@${dataAliasName}`, {
      requestTimeout: 20000,
      responseTimeout: 20000,
    })
    .should(xhr => { // change here
      cy.log('frist!: ' + JSON.stringify(xhr));
    })
    .then(xhr => {
      cy.log('2nd: ' + JSON.stringify(xhr)); // change here
      return cy.wrap({ documentId: xhr.response.body[0].id });
    })
    .as(documentIdAliasName);
}

Here's the request as logged to console by cypress:
image


Here is the xhr from cy.log, and it can be seen that the path exists and contains a value (warning: HUGE)

```javascript
let theXHR = {
xhr: {
method: 'GET',
url: 'https://dev630.metasfresh.com/rest/api/window/123/2156430',
id: 'xhr739',
},
id: 'xhr739',
url: 'https://dev630.metasfresh.com/rest/api/window/123/2156430',
method: 'GET',
status: 200,
statusMessage: '200 (OK)',
request: {
headers: {
Accept: 'application/json, text/plain, /',
'Accept-Language': 'en_US',
},
body: null,
},
response: {
headers: {
date: 'Tue, 06 Aug 2019 06:48:03 GMT',
'content-encoding': 'gzip',
server: 'nginx/1.10.3 (Ubuntu)',
vary: 'Accept-Encoding',
'access-control-allow-methods': 'POST, GET, OPTIONS, DELETE, PATCH, PUT',
'content-type': 'application/json;charset=UTF-8',
'access-control-allow-origin': 'http://localhost:3000',
'access-control-max-age': '600',
'transfer-encoding': 'chunked',
connection: 'keep-alive',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'x-requested-with, Content-Type, Origin, Accept-Language',
'x-application-context':
'metasfresh-webui-api:de.metas.vertical.healthcare.forum_datenaustausch_ch,metasfresh-webui-api:8443',
},
body: [
{
windowId: '123',
id: '2156430',
fieldsByName: {
ID: {
field: 'ID',
value: 2156430,
widgetType: 'Integer',
},
M_FreightCost_ID: {
field: 'M_FreightCost_ID',
value: null,
readonly: false,
mandatory: false,
displayed: true,
lookupValuesStale: true,
widgetType: 'List',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'M_FreightCost_ID',
},
viewEditorRenderMode: 'always',
},
M_Shipper_ID: {
field: 'M_Shipper_ID',
value: null,
readonly: false,
mandatory: false,
displayed: true,
lookupValuesStale: true,
widgetType: 'List',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'M_Shipper_ID',
},
viewEditorRenderMode: 'always',
},
AD_Client_ID: {
field: 'AD_Client_ID',
value: {
key: '1000000',
caption: 'metasfresh',
},
readonly: false,
mandatory: true,
displayed: true,
lookupValuesStale: true,
widgetType: 'List',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'AD_Client_ID',
},
viewEditorRenderMode: 'always',
},
AD_Org_ID: {
field: 'AD_Org_ID',
value: {
key: '1000000',
caption: 'metasfresh AG',
},
readonly: false,
mandatory: true,
displayed: true,
lookupValuesStale: true,
widgetType: 'List',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'AD_Org_ID',
},
viewEditorRenderMode: 'always',
},
Value: {
field: 'Value',
value: '1000004',
readonly: false,
mandatory: true,
displayed: true,
widgetType: 'Text',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'Value',
},
viewEditorRenderMode: 'always',
},
Name: {
field: 'Name',
value: 'vendor 1565074056375',
readonly: false,
mandatory: false,
displayed: false,
widgetType: 'Text',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'Name',
},
viewEditorRenderMode: 'always',
},
Name2: {
field: 'Name2',
value: 'vendor 1565074056375',
readonly: false,
mandatory: false,
displayed: true,
widgetType: 'Text',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'Name2',
},
viewEditorRenderMode: 'always',
},
Description: {
field: 'Description',
value: null,
readonly: false,
mandatory: false,
displayed: true,
widgetType: 'Text',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'Description',
},
viewEditorRenderMode: 'always',
},
IsActive: {
field: 'IsActive',
value: true,
readonly: false,
mandatory: true,
displayed: true,
widgetType: 'Switch',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'IsActive',
},
viewEditorRenderMode: 'always',
},
IsProducerAllotment: {
field: 'IsProducerAllotment',
value: false,
readonly: false,
mandatory: false,
displayed: true,
widgetType: 'YesNo',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'IsProducerAllotment',
},
viewEditorRenderMode: 'always',
},
IsCompany: {
field: 'IsCompany',
value: true,
readonly: false,
mandatory: false,
displayed: true,
widgetType: 'YesNo',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'IsCompany',
},
viewEditorRenderMode: 'always',
},
CompanyName: {
field: 'CompanyName',
value: 'vendor 1565074056375',
readonly: false,
mandatory: true,
displayed: true,
widgetType: 'Text',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'CompanyName',
},
viewEditorRenderMode: 'always',
},
VATaxID: {
field: 'VATaxID',
value: null,
readonly: false,
mandatory: false,
displayed: true,
widgetType: 'Text',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'VATaxID',
},
viewEditorRenderMode: 'always',
},
C_BP_Group_ID: {
field: 'C_BP_Group_ID',
value: {
key: '1000000',
caption: 'Standard',
},
readonly: false,
mandatory: true,
displayed: true,
lookupValuesStale: true,
widgetType: 'List',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'C_BP_Group_ID',
},
viewEditorRenderMode: 'always',
},
AD_Language: {
field: 'AD_Language',
value: {
key: 'en_US',
caption: 'English (US)',
},
readonly: false,
mandatory: false,
displayed: true,
lookupValuesStale: true,
widgetType: 'List',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'AD_Language',
},
viewEditorRenderMode: 'always',
},
IsEdiRecipient: {
field: 'IsEdiRecipient',
value: false,
readonly: false,
mandatory: true,
displayed: true,
widgetType: 'YesNo',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'IsEdiRecipient',
},
viewEditorRenderMode: 'always',
},
URL: {
field: 'URL',
value: null,
readonly: false,
mandatory: false,
displayed: true,
widgetType: 'Link',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'URL',
},
viewEditorRenderMode: 'always',
},
IsReplicationLookupDefault: {
field: 'IsReplicationLookupDefault',
value: false,
readonly: false,
mandatory: false,
displayed: true,
widgetType: 'YesNo',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'IsReplicationLookupDefault',
},
viewEditorRenderMode: 'always',
},
CreditLimitIndicator: {
field: 'CreditLimitIndicator',
value: null,
readonly: true,
mandatory: false,
displayed: true,
widgetType: 'Text',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'CreditLimitIndicator',
},
viewEditorRenderMode: 'never',
},
BPartner_Parent_ID: {
field: 'BPartner_Parent_ID',
value: null,
readonly: false,
mandatory: false,
displayed: true,
lookupValuesStale: true,
widgetType: 'Lookup',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'BPartner_Parent_ID',
},
viewEditorRenderMode: 'always',
},
Labels_548674: {
field: 'Labels_548674',
value: {
values: [],
},
readonly: false,
mandatory: false,
displayed: true,
lookupValuesStale: true,
widgetType: 'Labels',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'Labels_548674',
},
viewEditorRenderMode: 'always',
},
Labels_554470: {
field: 'Labels_554470',
value: {
values: [],
},
readonly: false,
mandatory: false,
displayed: true,
lookupValuesStale: true,
widgetType: 'Labels',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'Labels_554470',
},
viewEditorRenderMode: 'always',
},
V$DocumentSummary: {
field: 'V$DocumentSummary',
value: 'vendor 1565074056375 1000004',
readonly: true,
mandatory: false,
displayed: false,
widgetType: 'Text',
validStatus: {
valid: true,
initialValue: true,
fieldName: 'V$DocumentSummary',
},
viewEditorRenderMode: 'never',
},
},
validStatus: {
valid: true,
},
saveStatus: {
deleted: false,
saved: true,
hasChanges: false,
error: false,
reason: 'just loaded',
},
includedTabsInfo: {
'AD_Tab-541096': {
tabid: 'AD_Tab-541096',
allowCreateNew: true,
allowDelete: true,
},
'AD_Tab-540739': {
tabid: 'AD_Tab-540739',
allowCreateNew: false,
allowDelete: true,
},
'AD_Tab-540829': {
tabid: 'AD_Tab-540829',
allowCreateNew: false,
allowCreateNewReason: 'Tab is readonly',
allowDelete: false,
allowDeleteReason: 'Tab is readonly',
},
'AD_Tab-226': {
tabid: 'AD_Tab-226',
allowCreateNew: true,
allowDelete: true,
},
'AD_Tab-224': {
tabid: 'AD_Tab-224',
allowCreateNew: false,
allowDelete: true,
},
'AD_Tab-222': {
tabid: 'AD_Tab-222',
allowCreateNew: true,
allowDelete: true,
},
'AD_Tab-223': {
tabid: 'AD_Tab-223',
allowCreateNew: false,
allowDelete: true,
},
'AD_Tab-496': {
tabid: 'AD_Tab-496',
allowCreateNew: true,
allowDelete: true,
},
'AD_Tab-540737': {
tabid: 'AD_Tab-540737',
allowCreateNew: false,
allowCreateNewReason: 'Tab is readonly',
allowDelete: false,
allowDeleteReason: 'Tab is readonly',
},
'AD_Tab-541154': {
tabid: 'AD_Tab-541154',
allowCreateNew: false,
allowDelete: true,
},
'AD_Tab-541077': {
tabid: 'AD_Tab-541077',
allowCreateNew: true,
allowDelete: true,
},
'AD_Tab-541155': {
tabid: 'AD_Tab-541155',
allowCreateNew: true,
allowDelete: true,
},
'AD_Tab-540653': {
tabid: 'AD_Tab-540653',
allowCreateNew: true,
allowDelete: true,
},
'AD_Tab-540994': {
tabid: 'AD_Tab-540994',
allowCreateNew: true,
allowDelete: true,
},
},
standardActions: ['new', 'advancedEdit', 'email', 'letter', 'delete'],
websocketEndpoint: '/document/123/2156430',
},
],
},
duration: 395,
};

console.log(theXHR.response.body[0].id); // prints: "2156430"
````

Desired behavior:

Cypress should select the correct request and response.

Versions

Local machine: cypress 3.4.1, os: windows 10 x64, electron
Jenkins machine: cypress 3.4.1, os: some linux x64 VPS, electron

needs information

All 12 comments

Update: it seems that even expect(xhr.status).to.eq(200); as in https://github.com/metasfresh/metasfresh-e2e/blob/7de6c6098ef6a9d5150906298d46fc5836b3b60b/cypress/support/commands/general.js#L251 yelds a null/incomplete xhr: AssertionError: expected null to equal 200.
Here's the video of the problem: https://dashboard.cypress.io/#/projects/5yp4q1/runs/457/failures/744ef102-c167-49bf-ba44-9f7f203fbb6e

Hello,

Is there an update about tracking this issue down, as it keeps happening _(only when run in jenkins 馃檮)_ and it keeps breaking our tests :( ?

Here's more screenshots showing 2 xhr requests - one cancelled, one not - and cypress uses in wait for alias the cancelled request instead of the status 200 one:

Alias is "visitWindow-data-1568616033021".

  • first request is cancelled (id: 768):

image

  • second request is ok (id: 776)

image

  • the awaited request is the cancelled one, and not the ok one: xhr with id 768 is chosen instead of xhr with id 776 (why?)

image

I though i could add a .should section and maybe this would make cypress select the correct xhr via multiple retries, but the issue is the .then after the .should receives the XHR as null, contrary to what the docs say (that it returns the received parameter). Here's the relevant (failing with NPE) code:

    .wait(`@${dataAliasName}`, {
      requestTimeout: 20000,
      responseTimeout: 20000,
    })
    .should(xhr => {
      expect(xhr).to.not.be.empty;
      expect(xhr.status).to.eq(200);
      expect(xhr.response).to.not.be.empty;
      expect(xhr.response.body[0]).to.not.be.empty;
    })
    .then(xhr => {           // ERROR: xhr is null here, it is not passed from should, as expected from the docs
      cy.log('frist!: ' + JSON.stringify(xhr));
      cy.log('frist! x2: ' + JSON.stringify(xhr));
      cy.log('frist[0]: ' + JSON.stringify(xhr.response.body[0]));

      return cy.wrap({ documentId: xhr.response.body[0].id });
    })
    .as(documentIdAliasName);

Hi there, I'm also seeing this error occur nondeterministically and only within our CI environment, though for us we're seeing:

TypeError: Cannot read property 'requestBody' of null

I've tried upgrading to the latest version (3.8.2) to no avail. Any updates on what might be the cause/a workaround? It's causing our tests to be flaky.

I am also seeing this issue, however this is on my local machine, and the error reads:

Uncaught TypeError: Cannot read property 'pageCount' of null

Cypress 4.3.0
Chrome 80 / Electron 80
Windows 10

This issue only seems to happen when I am using a cookie that is redirecting the queries to the jenkins test environment. when I am using our production site this issue does not occur.

The issue does not happen every time I run the test, but it happens most times (7/10 test is red, 3/10 the test is green)

I am waiting for a route to exist:

    cy.visit('Website')
    cy.server()
    cy.route({
        method: 'POST',
        url: '/t/*',
    }).as('Dashboard-ready') //Checks that the final POST hase been received, allowing us to know when Dashboard is ready

    cy.wait('@Dashboard-ready', {timeout: 60000})

The cy.wait is where the error occurs.

Thanks @TheBestPessimist this was really bugging us in CI. The scenario you described wherein a previous aborted call to the same endpoint makes sense, but definitely unexpected.

Hey, I'm getting an error similar to the ones mentioned above. This starts happening from version 4.6.0, also happens in 4.7.0.

Full error:

cypress_runner.js:185054 TypeError: The following error originated from your application code, not from Cypress.

  > Cannot read property '__error' of null

When Cypress detects uncaught errors originating from your application it will automatically fail the current test.

This behavior is configurable, and you can choose to turn this off by listening to the `uncaught:exception` event.

Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `Takes longer`
    at XMLHttpRequest._getFixtureError (http://localhost:4000/__cypress/runner/cypress_runner.js:163144:22)
    at onLoadFn (http://localhost:4000/__cypress/runner/cypress_runner.js:161996:27)
    at XMLHttpRequest.<anonymous> (http://localhost:4000/__cypress/runner/cypress_runner.js:161980:25)
From previous event:
    at run (http://localhost:4000/__cypress/runner/cypress_runner.js:155845:19)
    at Object.cy.<computed> [as server] (http://localhost:4000/__cypress/runner/cypress_runner.js:156289:11)
    at Context.runnable.fn (http://localhost:4000/__cypress/runner/cypress_runner.js:156514:21)
    at callFn (http://localhost:4000/__cypress/runner/cypress_runner.js:95404:21)
    at Hook.../driver/node_modules/mocha/lib/runnable.js.Runnable.run (http://localhost:4000/__cypress/runner/cypress_runner.js:95391:7)
    at http://localhost:4000/__cypress/runner/cypress_runner.js:160893:28
From previous event:
    at Object.onRunnableRun (http://localhost:4000/__cypress/runner/cypress_runner.js:160881:20)
    at $Cypress.action (http://localhost:4000/__cypress/runner/cypress_runner.js:152580:61)
    at Hook.Runnable.run (http://localhost:4000/__cypress/runner/cypress_runner.js:159483:13)
    at next (http://localhost:4000/__cypress/runner/cypress_runner.js:95906:10)
    at http://localhost:4000/__cypress/runner/cypress_runner.js:95950:5
    at timeslice (http://localhost:4000/__cypress/runner/cypress_runner.js:89876:27)

This error pops up when a HTTP request from the application is not stubbed and it fails. When I stub them then the error goes away. In Cypress version 4.5.0 the same tests just work fine, so it can't be application code like the error suggests.

We are getting TypeError: Cannot read property 'requestBody' of null randomly in our CI workflows.

I'm having the same problem in GitHub Actions. Any updates on this?

@symon-skelly Your error does not look relevant to the originally opened issue. Please open a new issue with a reproducible example.
@KoenCa Your error is this one which was fixed in 4.8.0 https://github.com/cypress-io/cypress/issues/7518

@TheBestPessimist Can you give instructions on how and which tests to run to reproduce the error?

This should definitely not be happening. We'll need a reproducible example to track down the issue.

Hey @jennifer-shehane ,

In 699b42e (#369) we have removed the piece of code which created the most false-positives.

We have continued updating our product (e2e and production respectively) and right now we don't see this error happening. I'm not sure if not seeing it "at all" or extremely rarely. The colleague who works most with e2e these days sais he doesn't remember us having this error in the last 2+ months.

Therefore i'm sorry to say but i don't think i can help you with a repro anymore. I know it happened quite a lot when i opened the issue, but not right now.


Since I can no longer provide a "production" example, could any of the other participants here help?

@KoenCa Your error is this one which was fixed in 4.8.0

Yes, since 4.8.0 this doesn't happen anymore so my issue is fixed.

Was this page helpful?
0 / 5 - 0 ratings