diff --git a/content/_changelogs/12.0.0.md b/content/_changelogs/12.0.0.md
index 58151442cb..fac9213443 100644
--- a/content/_changelogs/12.0.0.md
+++ b/content/_changelogs/12.0.0.md
@@ -11,6 +11,11 @@ _Released MM/DD/YYYY_
- Cypress now throws an error if commands are invoked from inside a `.should()`
callback. This previously resulted in unusual and undefined behavior; it is
now explicitly an error.
+- The [`.within()`](/api/commands/within) command now throws an error if given
+ more than one DOM element as a subject. This is done for consistency - in
+ older versions, some commands inside a `.within()` block would respect all
+ passed in elements, while others silently discarded subjects beyond the first
+ and `.screenshot()` would throw an error.
- `Cookies.defaults` and `Cookies.preserveOnce` have been removed. Please update
to use [`cy.session()`](/api/commands/session) to preserve session details
between tests. Addresses
diff --git a/content/api/commands/within.md b/content/api/commands/within.md
index c73be241e1..649593ac31 100644
--- a/content/api/commands/within.md
+++ b/content/api/commands/within.md
@@ -20,7 +20,9 @@ chain further commands that rely on the subject after `.within()`.
** Correct Usage**
```javascript
-cy.get('.list').within(($list) => {}) // Yield the `.list` and scope all commands within it
+cy.get('.list')
+ .first()
+ .within(($list) => {}) // Yield the first `.list` and scope all commands within it
```
** Incorrect Usage**
@@ -28,6 +30,7 @@ cy.get('.list').within(($list) => {}) // Yield the `.list` and scope all command
```javascript
cy.within(() => {}) // Errors, cannot be chained off 'cy'
cy.getCookies().within(() => {}) // Errors, 'getCookies' does not yield DOM element
+cy.get('div').within(($divs) => {}) // Probably errors, because get('div') yields multiple elements
```
### Arguments
@@ -179,7 +182,8 @@ cy.get('form').within(($form) => {
### Requirements [](/guides/core-concepts/introduction-to-cypress#Chains-of-Commands)
-`.within()` requires being chained off a previous command.
+- `.within()` requires being chained off a previous command that yields exactly
+ one DOM element.
### Assertions [](/guides/core-concepts/introduction-to-cypress#Assertions)
@@ -211,10 +215,11 @@ outputs the following:
## History
-| Version | Changes |
-| --------------------------------------------- | ------------------------------------------------------- |
-| [< 0.3.3](/guides/references/changelog#0-3-3) | `.within()` command added |
-| [5.4.0](/guides/references/changelog#5-4-0) | fixed the yielded value to always be the parent element |
+| Version | Changes |
+| --------------------------------------------- | -------------------------------------------------------------------------------- |
+| [12.0.0](/guides/references/changelog#12-0-0) | `.within()` now throws an error when given more than one element as the subject. |
+| [5.4.0](/guides/references/changelog#5-4-0) | fixed the yielded value to always be the parent element |
+| [< 0.3.3](/guides/references/changelog#0-3-3) | `.within()` command added |
## See also
diff --git a/content/guides/references/migration-guide.md b/content/guides/references/migration-guide.md
index 32c89d05e2..206ad74472 100644
--- a/content/guides/references/migration-guide.md
+++ b/content/guides/references/migration-guide.md
@@ -269,9 +269,10 @@ command instead.
#### `.invoke()`
-[`.invoke()`](/api/commands/invoke) now throws an error if the function returns
-a promise. If you wish to call a method that returns a promise and wait for it
-to resolve, use [`.then()`](/api/commands/then) instead of `.invoke()`.
+The [`.invoke()`](/api/commands/invoke) command now throws an error if the
+function returns a promise. If you wish to call a method that returns a promise
+and wait for it to resolve, use [`.then()`](/api/commands/then) instead of
+`.invoke()`.
```diff
cy.wrap(myAPI)
@@ -296,7 +297,72 @@ assertions to their own chain. For example, rewrite
#### `.should()`
-[`.should()`](/api/commands/should) now throws an error if Cypress commands are
+The [`.should()`](/api/commands/should) assertion now throws an error if Cypress
+commands are invoked from inside a `.should()` callback. This previously
+resulted in unusual and undefined behavior. If you wish to execute a series of
+commands on the yielded value, use`.then()` instead.
+
+```diff
+cy.get('button')
+- .should(($button) => {
+
+ })
++ .then(api => api.makeARequest('http://example.com'))
+ .then(res => { ...handle response... })
+```
+
+#### `.within()`
+
+The [`.within()`](/api/commands/within) command now throws an error if it is
+passed multiple elements as the subject. This previously resulted in
+inconsistent behavior, where some commands would use all passed in elements,
+some would use only the first and ignore the rest, and
+[`.screenshot()`](/api/commands/screenshot) would throw an error if used inside
+a `.within()` block with multiple elements.
+
+If you were relying on the old behavior, you have several options depending on
+the desired result.
+
+The simplest option is to reduce the subject to a single element.
+
+```diff
+cy.get('tr')
++ .first() // Limit the subject to a single element before calling .within()
+ .within(() => {
+ cy.contains('Edit').click()
+ })
+```
+
+If you have multiple subjects and wish to run commands over the collection as a
+whole, you can alias the subject rather than use `.within()`.
+
+```diff
+cy.get('tr')
+- .within(() => {
+- cy.get('td').should('have.class', 'foo')
+- cy.get('td').should('have.class', 'bar')
+- })
++ .as('rows') // Store multiple elements as an alias
+
++cy.get('@rows').find('td').should('have.class', 'foo')
++cy.get('@rows').find('td').should('have.class', 'bar')
+```
+
+Or if you have a collection and want to run commands over every element, use
+`.each()` in conjunction with `.within()`.
+
+```diff
+cy.get('tr')
+- .within(() => {
+- cy.contains('Edit').should('have.attr', 'disabled')
+- })
++ .each($tr => {
++ cy.wrap($tr).within(() => {
++ cy.contains('Edit').should('have.attr', 'disabled')
++ })
++ })
+```
+
invoked from inside a `.should()` callback. This previously resulted in unusual
and undefined behavior. If you wish to execute a series of commands on the
yielded value, use`.then()` instead.