From 07e5a6a9e41943e0c3328841b3a856aa391e1e43 Mon Sep 17 00:00:00 2001 From: Nicholas Tindle Date: Tue, 21 Apr 2026 10:44:47 -0500 Subject: [PATCH 1/4] [Snyk] Security upgrade next from 15.4.10 to 15.4.11 (#12715) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ![snyk-top-banner](https://res.cloudinary.com/snyk/image/upload/r-d/scm-platform/snyk-pull-requests/pr-banner-default.svg) ### Snyk has created this PR to fix 1 vulnerabilities in the yarn dependencies of this project. #### Snyk changed the following file(s): - `autogpt_platform/frontend/package.json` #### Note for [zero-installs](https://yarnpkg.com/features/zero-installs) users If you are using the Yarn feature [zero-installs](https://yarnpkg.com/features/zero-installs) that was introduced in Yarn V2, note that this PR does not update the `.yarn/cache/` directory meaning this code cannot be pulled and immediately developed on as one would expect for a zero-install project - you will need to run `yarn` to update the contents of the `./yarn/cache` directory. If you are not using zero-install you can ignore this as your flow should likely be unchanged.
⚠️ Warning ``` Failed to update the yarn.lock, please update manually before merging. ```
#### Vulnerabilities that will be fixed with an upgrade: | | Issue | :-------------------------:|:------------------------- ![high severity](https://res.cloudinary.com/snyk/image/upload/w_20,h_20/v1561977819/icon/h.png 'high severity') | Allocation of Resources Without Limits or Throttling
[SNYK-JS-NEXT-15921797](https://snyk.io/vuln/SNYK-JS-NEXT-15921797) --- > [!IMPORTANT] > > - Check the changes in this PR to ensure they won't cause issues with your project. > - Max score is 1000. Note that the real score may have changed since the PR was raised. > - This PR was automatically created by Snyk using the credentials of a real user. --- **Note:** _You are seeing this because you or someone else with access to this repository has authorized Snyk to open fix PRs._ For more information: 🧐 [View latest project report](https://app.snyk.io/org/significant-gravitas/project/3d924968-0cf3-4767-9609-501fa4962856?utm_source=github&utm_medium=referral&page=fix-pr) πŸ“œ [Customise PR templates](https://docs.snyk.io/scan-using-snyk/pull-requests/snyk-fix-pull-or-merge-requests/customize-pr-templates?utm_source=github&utm_content=fix-pr-template) πŸ›  [Adjust project settings](https://app.snyk.io/org/significant-gravitas/project/3d924968-0cf3-4767-9609-501fa4962856?utm_source=github&utm_medium=referral&page=fix-pr/settings) πŸ“š [Read about Snyk's upgrade logic](https://docs.snyk.io/scan-with-snyk/snyk-open-source/manage-vulnerabilities/upgrade-package-versions-to-fix-vulnerabilities?utm_source=github&utm_content=fix-pr-template) --- **Learn how to fix vulnerabilities with free interactive lessons:** πŸ¦‰ [Allocation of Resources Without Limits or Throttling](https://learn.snyk.io/lesson/no-rate-limiting/?loc=fix-pr) [//]: # 'snyk:metadata:{"breakingChangeRiskLevel":null,"FF_showPullRequestBreakingChanges":false,"FF_showPullRequestBreakingChangesWebSearch":false,"customTemplate":{"variablesUsed":[],"fieldsUsed":[]},"dependencies":[{"name":"next","from":"15.4.10","to":"15.4.11"}],"env":"prod","issuesToFix":["SNYK-JS-NEXT-15921797"],"prId":"f3cd7cb3-bc59-4d03-8a12-19100988d06e","prPublicId":"f3cd7cb3-bc59-4d03-8a12-19100988d06e","packageManager":"yarn","priorityScoreList":[null],"projectPublicId":"3d924968-0cf3-4767-9609-501fa4962856","projectUrl":"https://app.snyk.io/org/significant-gravitas/project/3d924968-0cf3-4767-9609-501fa4962856?utm_source=github&utm_medium=referral&page=fix-pr","prType":"fix","templateFieldSources":{"branchName":"default","commitMessage":"default","description":"default","title":"default"},"templateVariants":["updated-fix-title","pr-warning-shown"],"type":"auto","upgrade":["SNYK-JS-NEXT-15921797"],"vulns":["SNYK-JS-NEXT-15921797"],"patch":[],"isBreakingChange":false,"remediationStrategy":"vuln"}' --- > [!NOTE] > **Medium Risk** > Patch-level upgrade of a core runtime/build dependency (Next.js) can affect app rendering/build behavior despite being scoped to dependency/lockfile changes. > > **Overview** > Upgrades the frontend framework dependency `next` from `15.4.10` to `15.4.11` in `package.json`. > > Updates `pnpm-lock.yaml` to reflect the new Next.js version (including `@next/env`) and re-resolves dependent packages that pin `next` in their peer/optional dependency graphs (e.g., `@sentry/nextjs`, `@vercel/analytics`, Storybook Next integration). > > Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit dc19e1f178167fab9017a06ee29aa9e27a54e17f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot). --------- Co-authored-by: snyk-bot Co-authored-by: Claude Opus 4.7 (1M context) --- autogpt_platform/frontend/package.json | 2 +- autogpt_platform/frontend/pnpm-lock.yaml | 76 ++++++++++++------------ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/autogpt_platform/frontend/package.json b/autogpt_platform/frontend/package.json index 292e64e8dd..9fa590c04e 100644 --- a/autogpt_platform/frontend/package.json +++ b/autogpt_platform/frontend/package.json @@ -96,7 +96,7 @@ "launchdarkly-react-client-sdk": "3.9.0", "lodash": "4.17.21", "lucide-react": "0.552.0", - "next": "15.4.10", + "next": "15.4.11", "next-themes": "0.4.6", "nuqs": "2.7.2", "posthog-js": "1.334.1", diff --git a/autogpt_platform/frontend/pnpm-lock.yaml b/autogpt_platform/frontend/pnpm-lock.yaml index ad6429ac52..a6ef21282c 100644 --- a/autogpt_platform/frontend/pnpm-lock.yaml +++ b/autogpt_platform/frontend/pnpm-lock.yaml @@ -26,7 +26,7 @@ importers: version: 5.2.2(react-hook-form@7.66.0(react@18.3.1)) '@next/third-parties': specifier: 15.4.6 - version: 15.4.6(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 15.4.6(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@phosphor-icons/react': specifier: 2.1.10 version: 2.1.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -107,7 +107,7 @@ importers: version: 6.1.2(@rjsf/utils@6.1.2(react@18.3.1)) '@sentry/nextjs': specifier: 10.27.0 - version: 10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.104.1(esbuild@0.25.12)) + version: 10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.104.1(esbuild@0.25.12)) '@streamdown/cjk': specifier: 1.0.1 version: 1.0.1(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(react@18.3.1)(unified@11.0.5) @@ -134,10 +134,10 @@ importers: version: 0.2.4 '@vercel/analytics': specifier: 1.5.0 - version: 1.5.0(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 1.5.0(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@vercel/speed-insights': specifier: 1.2.0 - version: 1.2.0(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 1.2.0(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@xyflow/react': specifier: 12.9.2 version: 12.9.2(@types/react@18.3.17)(immer@11.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -185,7 +185,7 @@ importers: version: 12.23.24(@emotion/is-prop-valid@1.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) geist: specifier: 1.5.1 - version: 1.5.1(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + version: 1.5.1(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) highlight.js: specifier: 11.11.1 version: 11.11.1 @@ -205,14 +205,14 @@ importers: specifier: 0.552.0 version: 0.552.0(react@18.3.1) next: - specifier: 15.4.10 - version: 15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 15.4.11 + version: 15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-themes: specifier: 0.4.6 version: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nuqs: specifier: 2.7.2 - version: 2.7.2(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 2.7.2(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) posthog-js: specifier: 1.334.1 version: 1.334.1 @@ -330,7 +330,7 @@ importers: version: 9.1.5(storybook@9.1.5(@testing-library/dom@10.4.1)(msw@2.11.6(@types/node@24.10.0)(typescript@5.9.3))(prettier@3.6.2)(vite@7.3.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2))) '@storybook/nextjs': specifier: 9.1.5 - version: 9.1.5(esbuild@0.25.12)(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.5(@testing-library/dom@10.4.1)(msw@2.11.6(@types/node@24.10.0)(typescript@5.9.3))(prettier@3.6.2)(vite@7.3.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2)))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(esbuild@0.25.12)) + version: 9.1.5(esbuild@0.25.12)(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.5(@testing-library/dom@10.4.1)(msw@2.11.6(@types/node@24.10.0)(typescript@5.9.3))(prettier@3.6.2)(vite@7.3.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2)))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(esbuild@0.25.12)) '@tanstack/eslint-plugin-query': specifier: 5.91.2 version: 5.91.2(eslint@8.57.1)(typescript@5.9.3) @@ -1844,8 +1844,8 @@ packages: '@neoconfetti/react@1.0.0': resolution: {integrity: sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==} - '@next/env@15.4.10': - resolution: {integrity: sha512-knhmoJ0Vv7VRf6pZEPSnciUG1S4bIhWx+qTYBW/AjxEtlzsiNORPk8sFDCEvqLfmKuey56UB9FL1UdHEV3uBrg==} + '@next/env@15.4.11': + resolution: {integrity: sha512-mIYp/091eYfPFezKX7ZPTWqrmSXq+ih6+LcUyKvLmeLQGhlPtot33kuEOd4U+xAA7sFfj21+OtCpIZx0g5SpvQ==} '@next/eslint-plugin-next@15.5.7': resolution: {integrity: sha512-DtRU2N7BkGr8r+pExfuWHwMEPX5SD57FeA6pxdgCHODo+b/UgIgjE+rgWKtJAbEbGhVZ2jtHn4g3wNhWFoNBQQ==} @@ -6839,8 +6839,8 @@ packages: react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - next@15.4.10: - resolution: {integrity: sha512-itVlc79QjpKMFMRhP+kbGKaSG/gZM6RCvwhEbwmCNF06CdDiNaoHcbeg0PqkEa2GOcn8KJ0nnc7+yL7EjoYLHQ==} + next@15.4.11: + resolution: {integrity: sha512-IJRyXal45mIsshZI5XJne/intjusslUP1F+FHVBIyMGEqbYtIq1Irdx5vdWBBg58smviPDycmDeV6txsfkv1RQ==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -10423,7 +10423,7 @@ snapshots: '@neoconfetti/react@1.0.0': {} - '@next/env@15.4.10': {} + '@next/env@15.4.11': {} '@next/eslint-plugin-next@15.5.7': dependencies: @@ -10453,9 +10453,9 @@ snapshots: '@next/swc-win32-x64-msvc@15.4.8': optional: true - '@next/third-parties@15.4.6(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@next/third-parties@15.4.6(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: - next: 15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 third-party-capital: 1.0.20 @@ -11770,7 +11770,7 @@ snapshots: '@sentry/core@10.27.0': {} - '@sentry/nextjs@10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.104.1(esbuild@0.25.12))': + '@sentry/nextjs@10.27.0(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.104.1(esbuild@0.25.12))': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.38.0 @@ -11783,7 +11783,7 @@ snapshots: '@sentry/react': 10.27.0(react@18.3.1) '@sentry/vercel-edge': 10.27.0 '@sentry/webpack-plugin': 4.6.1(webpack@5.104.1(esbuild@0.25.12)) - next: 15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) resolve: 1.22.8 rollup: 4.55.1 stacktrace-parser: 0.1.11 @@ -12162,7 +12162,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/nextjs@9.1.5(esbuild@0.25.12)(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.5(@testing-library/dom@10.4.1)(msw@2.11.6(@types/node@24.10.0)(typescript@5.9.3))(prettier@3.6.2)(vite@7.3.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2)))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(esbuild@0.25.12))': + '@storybook/nextjs@9.1.5(esbuild@0.25.12)(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.5(@testing-library/dom@10.4.1)(msw@2.11.6(@types/node@24.10.0)(typescript@5.9.3))(prettier@3.6.2)(vite@7.3.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2)))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(esbuild@0.25.12))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.5) @@ -12186,7 +12186,7 @@ snapshots: css-loader: 6.11.0(webpack@5.104.1(esbuild@0.25.12)) image-size: 2.0.2 loader-utils: 3.3.1 - next: 15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) node-polyfill-webpack-plugin: 2.0.1(webpack@5.104.1(esbuild@0.25.12)) postcss: 8.5.6 postcss-loader: 8.2.0(postcss@8.5.6)(typescript@5.9.3)(webpack@5.104.1(esbuild@0.25.12)) @@ -12872,16 +12872,16 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@vercel/analytics@1.5.0(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@vercel/analytics@1.5.0(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': optionalDependencies: - next: 15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 '@vercel/oidc@3.1.0': {} - '@vercel/speed-insights@1.2.0(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@vercel/speed-insights@1.2.0(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': optionalDependencies: - next: 15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 '@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.1)(yaml@2.8.2))': @@ -14449,8 +14449,8 @@ snapshots: '@typescript-eslint/parser': 8.52.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.5(eslint@8.57.1) eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1) @@ -14469,7 +14469,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 @@ -14480,22 +14480,22 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.52.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -14506,7 +14506,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.52.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -14877,9 +14877,9 @@ snapshots: functions-have-names@1.2.3: {} - geist@1.5.1(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): + geist@1.5.1(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): dependencies: - next: 15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) generator-function@2.0.1: {} @@ -16465,9 +16465,9 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 15.4.10 + '@next/env': 15.4.11 '@swc/helpers': 0.5.15 caniuse-lite: 1.0.30001762 postcss: 8.4.31 @@ -16569,12 +16569,12 @@ snapshots: dependencies: boolbase: 1.0.0 - nuqs@2.7.2(next@15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): + nuqs@2.7.2(next@15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): dependencies: '@standard-schema/spec': 1.0.0 react: 18.3.1 optionalDependencies: - next: 15.4.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.4.11(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) oas-kit-common@1.0.8: dependencies: From 6924cf90a5627086ec017a806bb611ba5db0ae79 Mon Sep 17 00:00:00 2001 From: Nicholas Tindle Date: Tue, 21 Apr 2026 10:53:01 -0500 Subject: [PATCH 2/4] fix(frontend/copilot): artifact panel fixes (SECRT-2254/2223/2220/2255/2224/2256/2221) (#12856) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Why / What / How https://github.com/user-attachments/assets/ca26e0b0-d35d-4a5b-b95f-2421b9907742 **Why** β€” The Artifact & Side Task List project (https://linear.app/autogpt/project/artifact-and-side-task-list-ef863c93da3c) accumulated seven related bugs in the copilot artifact panel. The user kept seeing panels stuck open, previews broken, clicks not registering β€” each ticket was small but they all lived in the same small surface area, so one review pass is easier than five. Closes SECRT-2254, SECRT-2223, SECRT-2220, SECRT-2255, SECRT-2224, SECRT-2256, SECRT-2221. **What** β€” Five independent fixes, each in its own commit, shipped together: 1. **Fragment-link interceptor + render error boundary** (SECRT-2255 crash when clicking `` in HTML artifacts). Sandboxed srcdoc iframes resolve fragment links against the parent's URL, so clicking `#activation` in a Plotly TOC tried to navigate the copilot page into the iframe. Inject a click-capture script into every artifact iframe; also wrap the renderer in `ArtifactErrorBoundary` so any future render throw surfaces with a copyable error instead of a blank panel. 2. **Close panel on copilot page unmount** (SECRT-2254 / 2223 / 2220 β€” panel stays open, reopens on unrelated navigation, opens by default on session switch). The Zustand store outlived page unmounts, so `isOpen: true` survived `/profile` β†’ `/home` β†’ back. One `useEffect` cleanup in `useAutoOpenArtifacts` calls `resetArtifactPanel()` on unmount. 3. **Sync loading flip on Try Again** (SECRT-2224 "try again doesn't do anything"). Retry was correct but the loading-state flip was deferred to an effect, so a retry that re-failed was visually indistinguishable from a no-op. `retry()` now sets `isLoading: true` / `error: null` synchronously with the click so the skeleton flashes every time. 4. **Pointer capture on resize drag** (SECRT-2256 "can't drag right when expanded far left, click doesn't stop it"). The sandboxed iframe was eating `pointermove`/`pointerup` events when the cursor drifted over it, freezing the drag and never delivering the release. `setPointerCapture` on the handle routes all subsequent pointer events through it regardless of what's under the cursor. 5. **Stop size-gating natively-rendered artifacts + cache-bust retry** (SECRT-2221 "broken hi-res PNG preview"). The blanket >10 MB size gate pushed large images / videos / PDFs into `download-only`, so clicking a hi-res PNG offered a download instead of a preview. Split the gate so it only applies to content we actually render in JS (text/html/code/etc). Image and video retries also append a cache-bust query so the browser can't silently reuse a negative-cached failure. **How** β€” Five commits, one concern each, preserved in the order they were written. Every fix lands with a regression test that fails on the unfixed code and passes after. ### Changes πŸ—οΈ - `iframe-sandbox-csp.ts` + usage sites β€” `FRAGMENT_LINK_INTERCEPTOR_SCRIPT` injected into all three srcdoc iframe templates (HTML artifact, inline HTMLRenderer, React artifact). - `ArtifactErrorBoundary.tsx` (new) β€” class error boundary local to the artifact panel with a copyable error fallback. - `useAutoOpenArtifacts.ts` β€” unmount cleanup calls `resetArtifactPanel()`. - `useArtifactContent.ts` β€” `retry()` flips loading state synchronously. - `ArtifactDragHandle.tsx` β€” `setPointerCapture` / `releasePointerCapture`; `touch-action: none`. - `helpers.ts` β€” split classifier; `NATIVELY_RENDERED` exempts image/video/pdf from the size gate. - `ArtifactContent.tsx` β€” image/video carry a retry nonce that appends `?_retry=N` on Try Again. - Test files β€” new `ArtifactErrorBoundary`/`ArtifactDragHandle`/`HTMLRenderer` tests, plus regression cases added to `ArtifactContent.test.tsx`, `helpers.test.ts`, `iframe-sandbox-csp.test.ts`, `reactArtifactPreview.test.ts`, `useAutoOpenArtifacts.test.ts`. ### Checklist πŸ“‹ #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] `pnpm vitest run src/app/\(platform\)/copilot src/components/contextual/OutputRenderers src/lib/__tests__/iframe-sandbox-csp.test.ts` β€” 247/247 pass - [x] `pnpm format && pnpm types` clean - [x] Manual: open the Plotly-style TOC HTML artifact (SECRT-2255 repro), click each anchor β€” iframe scrolls internally, browser URL bar stays put - [x] Manual: open panel β†’ navigate to /profile β†’ navigate back β†’ panel closed (SECRT-2254) - [x] Manual: panel open in session A β†’ click different session β†’ panel closed (SECRT-2223) - [ ] Manual: simulate a failed artifact fetch β†’ click Try Again β†’ skeleton flashes before result (SECRT-2224) - [x] Manual: expand panel to near-full width β†’ drag back right, crossing over the iframe β†’ drag keeps working and release ends it (SECRT-2256) - [x] Manual: upload a ~25 MB PNG β†’ clicking it previews in an ``, not a download button (SECRT-2221) Replaces #12836, #12837, #12838, #12839, #12840 β€” same fixes, bundled for review. --- > [!NOTE] > **Medium Risk** > Touches artifact rendering and iframe `srcDoc` generation (including injected scripts) plus panel state/drag interactions; regressions could break previews or resizing, but changes are scoped to the copilot artifact UI with broad test coverage. > > **Overview** > Improves Copilot’s artifact panel resilience and UX by **resetting panel state on page unmount/session changes**, making content retries immediately show the loading skeleton, and fixing resize drags via pointer capture so iframes can’t β€œsteal” pointer events. > > Hardens artifact rendering by adding a local `ArtifactErrorBoundary` that reports to Sentry and shows a copyable error fallback instead of a blank/crashed panel. > > Fixes iframe-based previews by injecting a `FRAGMENT_LINK_INTERCEPTOR_SCRIPT` into HTML and React artifact `srcDoc` so `#anchor` clicks scroll within the iframe rather than navigating the parent URL, and adjusts artifact classification/retry behavior so large images/videos/PDFs remain previewable and image/video retries cache-bust failed URLs. > > Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit bde37a13fd135f13639be1398506160147de1b7b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot). --------- Co-authored-by: Claude Opus 4.7 (1M context) --- .../components/ArtifactContent.tsx | 43 +- .../components/ArtifactDragHandle.tsx | 31 +- .../components/ArtifactErrorBoundary.tsx | 100 ++++ .../__tests__/ArtifactContent.test.tsx | 455 ++++++++++++++++++ .../__tests__/ArtifactDragHandle.test.tsx | 181 +++++++ .../reactArtifactPreview.test.ts | 9 +- .../components/reactArtifactPreview.ts | 6 +- .../components/useArtifactContent.ts | 5 + .../components/ArtifactPanel/helpers.test.ts | 23 +- .../components/ArtifactPanel/helpers.ts | 24 +- .../useAutoOpenArtifacts.test.ts | 58 ++- .../ChatContainer/useAutoOpenArtifacts.ts | 9 + .../renderers/HTMLRenderer.test.tsx | 54 +++ .../renderers/HTMLRenderer.tsx | 6 +- .../lib/__tests__/iframe-sandbox-csp.test.ts | 144 +++++- .../frontend/src/lib/iframe-sandbox-csp.ts | 32 ++ 16 files changed, 1159 insertions(+), 21 deletions(-) create mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/ArtifactPanel/components/ArtifactErrorBoundary.tsx create mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/ArtifactPanel/components/__tests__/ArtifactDragHandle.test.tsx rename autogpt_platform/frontend/src/app/(platform)/copilot/components/ArtifactPanel/components/{ => __tests__}/reactArtifactPreview.test.ts (92%) create mode 100644 autogpt_platform/frontend/src/components/contextual/OutputRenderers/renderers/HTMLRenderer.test.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/ArtifactPanel/components/ArtifactContent.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/ArtifactPanel/components/ArtifactContent.tsx index 506cbc3b60..7a65188b86 100644 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/ArtifactPanel/components/ArtifactContent.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/copilot/components/ArtifactPanel/components/ArtifactContent.tsx @@ -6,9 +6,11 @@ import { Suspense, useState } from "react"; import { Skeleton } from "@/components/ui/skeleton"; import type { ArtifactRef } from "../../../store"; import type { ArtifactClassification } from "../helpers"; +import { ArtifactErrorBoundary } from "./ArtifactErrorBoundary"; import { ArtifactReactPreview } from "./ArtifactReactPreview"; import { ArtifactSkeleton } from "./ArtifactSkeleton"; import { + FRAGMENT_LINK_INTERCEPTOR_SCRIPT, TAILWIND_CDN_URL, wrapWithHeadInjection, } from "@/lib/iframe-sandbox-csp"; @@ -53,20 +55,35 @@ function ArtifactContentLoader({ return (
- + + +
); } +function withCacheBust(src: string, nonce: number): string { + if (nonce === 0) return src; + const sep = src.includes("?") ? "&" : "?"; + return `${src}${sep}_retry=${nonce}`; +} + function ArtifactImage({ src, alt }: { src: string; alt: string }) { const [loaded, setLoaded] = useState(false); const [error, setError] = useState(false); + // Incremented on every Try Again so the URL changes and the browser + // can't reuse a negative-cached response (SECRT-2221). + const [retryNonce, setRetryNonce] = useState(0); if (error) { return ( @@ -80,6 +97,7 @@ function ArtifactImage({ src, alt }: { src: string; alt: string }) { onClick={() => { setError(false); setLoaded(false); + setRetryNonce((n) => n + 1); }} className="rounded-md border border-zinc-200 bg-white px-3 py-1.5 text-xs font-medium text-zinc-700 shadow-sm transition-colors hover:bg-zinc-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400" > @@ -96,7 +114,7 @@ function ArtifactImage({ src, alt }: { src: string; alt: string }) { )} {/* eslint-disable-next-line @next/next/no-img-element */} {alt} setLoaded(true)} @@ -109,6 +127,7 @@ function ArtifactImage({ src, alt }: { src: string; alt: string }) { function ArtifactVideo({ src }: { src: string }) { const [loaded, setLoaded] = useState(false); const [error, setError] = useState(false); + const [retryNonce, setRetryNonce] = useState(0); if (error) { return ( @@ -122,6 +141,7 @@ function ArtifactVideo({ src }: { src: string }) { onClick={() => { setError(false); setLoaded(false); + setRetryNonce((n) => n + 1); }} className="rounded-md border border-zinc-200 bg-white px-3 py-1.5 text-xs font-medium text-zinc-700 shadow-sm transition-colors hover:bg-zinc-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-400" > @@ -137,7 +157,7 @@ function ArtifactVideo({ src }: { src: string }) { )}