{"record":{"id":"d9a127c7aa5272d9","repo":"cypress-io/cypress","slug":"cy-visit-from-a-component-spec-is-not-allowed","errorCode":null,"errorMessage":"cy.visit from a component spec is not allowed","messagePattern":"cy\\.visit from a component spec is not allowed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"npm/mount-utils/src/index.ts","lineNumber":34,"sourceCode":"}\n\n/**\n * Utility function to register CT side effects and run cleanup code during the \"test:before:run\" Cypress hook\n * @param optionalCallback Callback to be called before the next test runs\n */\nexport function setupHooks (optionalCallback?: Function) {\n  // We don't want CT side effects to run when e2e\n  // testing so we early return.\n  // System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts\n  if (Cypress.testingType !== 'component') {\n    return\n  }\n\n  // When running component specs, we cannot allow \"cy.visit\"\n  // because it will wipe out our preparation work, and does not make much sense\n  // thus we overwrite \"cy.visit\" to throw an error\n  Cypress.Commands.overwrite('visit', () => {\n    throw new Error(\n      'cy.visit from a component spec is not allowed',\n    )\n  })\n\n  Cypress.Commands.overwrite('session', () => {\n    throw new Error(\n      'cy.session from a component spec is not allowed',\n    )\n  })\n\n  Cypress.Commands.overwrite('origin', () => {\n    throw new Error(\n      'cy.origin from a component spec is not allowed',\n    )\n  })\n\n  // @ts-ignore\n  Cypress.on('test:before:after:run:async', () => {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/cypress-io/cypress/blob/0d85fdc91230885bca0a91df278312800a48b727/npm/mount-utils/src/index.ts#L16-L52","documentation":"Thrown by @cypress/mount-utils setupHooks, which overwrites the `visit` command during component testing (testingType === 'component'). In CT the AUT iframe already hosts the mounted component; calling cy.visit would navigate away, destroy the mounted DOM and React/Vue state, and is semantically meaningless. The overwrite unconditionally throws whenever the command is invoked.","triggerScenarios":"Calling `cy.visit(url)` inside a component spec (a *.cy.{tsx,jsx,vue,...} file run with testingType='component'). The guard fires only after setupHooks has run, which happens for every CT run.","commonSituations":"Copy-pasting an e2e pattern into a component spec; testing a component that loads external routes and forgetting CT mounts the component directly; a shared support file imported by both e2e and CT specs that calls visit.","solutions":["Remove the cy.visit call from the component spec — CT does not navigate, it mounts.","If you need to set route state, mock it via cy.intercept or pass props to the mounted component instead.","Move any cy.visit usage to an e2e spec (testingType='e2e') where it belongs.","If the visit is in a shared support file, gate it behind `if (Cypress.testingType === 'e2e')`."],"exampleFix":"// before (component spec)\nbeforeEach(() => { cy.visit('/dashboard') })\nit('shows widget', () => { cy.mount(<Dashboard/>) })\n// after\nit('shows widget', () => { cy.mount(<Dashboard user={{name:'Sam'}}/>) })","handlingStrategy":"type-guard","validationCode":"// never call cy.visit in CT specs; gate shared helpers\nif (Cypress.testingType === 'e2e') { cy.visit(url) }","typeGuard":"const isE2E = (): boolean => Cypress.testingType === 'e2e'","tryCatchPattern":null,"preventionTips":["Split support files so navigation helpers are only imported by e2e specs.","Use cy.mount in CT instead of cy.visit.","Lint for cy.visit inside *.cy.{tsx,jsx,vue} with a custom ESLint rule."],"tags":["component-testing","mount-utils","forbidden-command","cy-visit"],"backgroundTag":null,"analyzedSha":"0d85fdc91230885bca0a91df278312800a48b727","analyzedAt":"2026-08-12T16:24:28.056Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}