Skip to content

Handle agent-network settings defaults response - #739

Merged
mlsmaycon merged 3 commits into
mainfrom
agent-network-settings-defaults
Aug 3, 2026
Merged

Handle agent-network settings defaults response#739
mlsmaycon merged 3 commits into
mainfrom
agent-network-settings-defaults

Conversation

@mlsmaycon

@mlsmaycon mlsmaycon commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Issue ticket number and link

NET-1465 — companion to netbirdio/netbird#7026, where the management API's settings GET now answers the unbootstrapped state with a defaults object (empty cluster/subdomain/endpoint) instead of a JSON null body.

useAgentNetworkSettings normalizes that shape to the existing settings === null signal, so every consumer keeps a single not-bootstrapped check. The null body and 404 from older backends still normalize the same way, so the dashboard works against both server generations. created_at/updated_at become optional in the API type since they are absent until a row is persisted.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why): internal handling of an API response shape; no user-facing behavior change.

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

https://github.com/netbirdio/docs/pull/__

E2E tests

Optional: override the image tags used by the Playwright e2e workflow.
Defaults to main when omitted.

management-cloud-tag: main
reverse-proxy-tag: main


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of missing or unavailable agent-network settings.
    • Prevented outdated settings from appearing after a not-found response.
    • Correctly displays the provider empty state when settings are unavailable.
    • Preserved configured endpoints when valid settings are returned.
  • Tests

    • Added end-to-end coverage for default, empty, not-found, and configured settings responses.

The management API now answers the settings GET with a defaults object
before the account is bootstrapped (empty cluster/subdomain/endpoint)
instead of a JSON null body. Normalize that shape to the existing null
settings signal so every consumer keeps a single not-bootstrapped check,
while still tolerating the null body and 404 from older backends.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 23577475-9df5-4db1-934d-1fd6d3d1986c

📥 Commits

Reviewing files that changed from the base of the PR and between f73cf5b and fb6438e.

📒 Files selected for processing (2)
  • e2e/tests/agent-network-settings-shapes.spec.ts
  • src/modules/agent-network/AIProvidersProvider.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • e2e/tests/agent-network-settings-shapes.spec.ts
  • src/modules/agent-network/AIProvidersProvider.tsx

📝 Walkthrough

Walkthrough

The provider now normalizes missing agent-network endpoints and 404 responses as unbootstrapped settings. End-to-end tests cover default-only, null, 404, and configured settings responses.

Changes

Agent network settings

Layer / File(s) Summary
Settings response normalization
src/modules/agent-network/AIProvidersProvider.tsx
APIAgentNetworkSettings permits absent timestamps. Missing endpoints and 404 responses normalize to null. Other transient errors retain existing data.
Settings shape end-to-end coverage
e2e/tests/agent-network-settings-shapes.spec.ts
Tests mock default-only, null, 404, and configured settings responses. Unbootstrapped responses render the empty state, while configured settings render the endpoint.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProvidersPage
  participant AIProvidersProvider
  participant SettingsAPI
  ProvidersPage->>AIProvidersProvider: Load agent-network settings
  AIProvidersProvider->>SettingsAPI: Request settings
  SettingsAPI-->>AIProvidersProvider: Defaults, null, 404, or configured settings
  AIProvidersProvider-->>ProvidersPage: Null or normalized settings
  ProvidersPage-->>ProvidersPage: Render empty state or configured endpoint
Loading

Possibly related PRs

Suggested reviewers: braginini

Poem

A rabbit checks the settings gate,
Finds empty fields and waits their fate.
Null and 404 now guide the way,
Configured endpoints proudly stay.
Tests hop through each response shape.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description includes the issue link, change summary, documentation decision with justification, and E2E workflow settings.
Title check ✅ Passed The title clearly summarizes the main change to agent-network settings defaults response handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent-network-settings-defaults

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

e2e/tests/agent-network-settings-shapes.spec.ts

Oops! Something went wrong! :(

ESLint: 9.39.3

TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'configs' -> object with constructor 'Object'
| property 'flat' -> object with constructor 'Object'
| ...
| property 'plugins' -> object with constructor 'Object'
--- property 'react' closes the circle
Referenced from: /.eslintrc.json
at JSON.stringify ()
at /node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2255:45
at Array.map ()
at ConfigValidator.formatErrors (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2246:23)
at ConfigValidator.validateConfigSchema (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2277:84)
at ConfigArrayFactory._normalizeConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3123:19)
at ConfigArrayFactory._loadConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3088:21)
at ConfigArrayFactory._loadExtendedShareableConfig (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3393:21)
at ConfigArrayFactory._loadExtends (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3261:25)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3199:25)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)

src/modules/agent-network/AIProvidersProvider.tsx

Oops! Something went wrong! :(

ESLint: 9.39.3

TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'configs' -> object with constructor 'Object'
| property 'flat' -> object with constructor 'Object'
| ...
| property 'plugins' -> object with constructor 'Object'
--- property 'react' closes the circle
Referenced from: /.eslintrc.json
at JSON.stringify ()
at /node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2255:45
at Array.map ()
at ConfigValidator.formatErrors (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2246:23)
at ConfigValidator.validateConfigSchema (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2277:84)
at ConfigArrayFactory._normalizeConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3123:19)
at ConfigArrayFactory._loadConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3088:21)
at ConfigArrayFactory._loadExtendedShareableConfig (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3393:21)
at ConfigArrayFactory._loadExtends (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3261:25)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3199:25)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The providers page must render the connect-first empty state for every
unbootstrapped settings shape the management API has answered with over
time (defaults object with an empty endpoint, JSON null body, 404) and
the endpoint badge once bootstrapped. The settings route is mocked per
test so the spec is independent of the backend build and of account
state left behind by other suites.
@linear-code

linear-code Bot commented Aug 2, 2026

Copy link
Copy Markdown

NET-1465

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
e2e/tests/agent-network-settings-shapes.spec.ts (5)

80-84: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Use navigateTo for the providers navigation.

page.goto() followed by page.keyboard.press("Escape") does not apply the setup-modal dismissal and scroll-lock cleanup provided by navigateTo. Replace this pair with navigateTo(page, "/agent-network/providers").

As per coding guidelines, use navigateTo(page, path) instead of direct page.goto().

Suggested change
-  await page.goto("/agent-network/providers");
-  await page.keyboard.press("Escape");
+  await navigateTo(page, "/agent-network/providers");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/tests/agent-network-settings-shapes.spec.ts` around lines 80 - 84, In the
setup flow returning the page and close handler, replace the direct
page.goto("/agent-network/providers") plus Escape keypress with navigateTo(page,
"/agent-network/providers"), preserving the existing login and return behavior.

Source: Coding guidelines


108-109: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a serial test suite.

Change test.describe to test.describe.serial. This follows the required E2E suite structure.

As per coding guidelines, organize test specs with test.describe.serial().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/tests/agent-network-settings-shapes.spec.ts` around lines 108 - 109,
Update the suite declaration around UNBOOTSTRAPPED_SHAPES from test.describe to
test.describe.serial, preserving the existing suite body and test structure.

Source: Coding guidelines


80-84: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Wait for the settings response before asserting the rendered state.

Start page.waitForResponse() before navigation. Match GET requests to /api/agent-network/settings and set a timeout. Await the response before returning from openProvidersPage.

Without this wait, assertions can observe the initial UI before the settings hook consumes the mock. The PR objective is to verify each response shape.

As per coding guidelines, wait for specific API responses with page.waitForResponse() before assertions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/tests/agent-network-settings-shapes.spec.ts` around lines 80 - 84, Update
openProvidersPage to start page.waitForResponse before navigating to
/agent-network/providers, matching the GET /api/agent-network/settings request
with a timeout. Await that response after navigation and before returning the
page so assertions observe the rendered state after the mocked settings response
is consumed.

Source: Coding guidelines


115-116: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use data-testid selectors for state assertions.

Replace the page.getByText() locators with page.getByTestId() locators for the empty state and endpoint. If the components do not expose test IDs, add optional data-testid?: string props and use stable kebab-case IDs.

As per coding guidelines, Playwright specs must use page.getByTestId() for element selection.

Also applies to: 131-132

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/tests/agent-network-settings-shapes.spec.ts` around lines 115 - 116,
Replace the page.getByText() assertions in the agent network settings test,
including the additional assertions at the referenced later range, with
page.getByTestId() using stable kebab-case IDs for the empty state and
bootstrapped endpoint. If those components lack test IDs, add optional
data-testid props and pass the corresponding IDs through their render paths.

Source: Coding guidelines


15-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use dashboardAsOwner for agent-network spec authentication.

e2e/tests/**/*.spec.ts must use custom fixtures instead of raw-page logins. Replace the local Browser+owner.json+loginToApp(page, "owner") flow with an injected dashboardAsOwner page, and move the e2e/fixtures/auth/owner.json feature-flag logic into the fixture lifecycle.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/tests/agent-network-settings-shapes.spec.ts` around lines 15 - 16, The
agent-network spec should use the custom dashboardAsOwner fixture instead of raw
Browser/Page authentication. Update the test setup and test signatures to inject
dashboardAsOwner, remove the Browser and loginToApp imports/usages, and relocate
the owner.json feature-flag setup into the fixture lifecycle while preserving
the existing test behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/tests/agent-network-settings-shapes.spec.ts`:
- Around line 68-84: Update openProvidersPage so browser context cleanup is
handled during setup: wrap context creation and subsequent initialization in
try/catch or try/finally, close the context if mockSettingsResponse, loginToApp,
navigation, or other setup steps fail, then rethrow the original error; preserve
the existing close callback on successful setup.

In `@src/modules/agent-network/AIProvidersProvider.tsx`:
- Around line 542-545: Update the settings memo in AIProvidersProvider around
settingsFromAPI so it returns null whenever the request has a 404 error, even if
keepPreviousData supplies stale data. Include notFound in the predicate and add
both error and notFound to the memo dependency array.

---

Nitpick comments:
In `@e2e/tests/agent-network-settings-shapes.spec.ts`:
- Around line 80-84: In the setup flow returning the page and close handler,
replace the direct page.goto("/agent-network/providers") plus Escape keypress
with navigateTo(page, "/agent-network/providers"), preserving the existing login
and return behavior.
- Around line 108-109: Update the suite declaration around UNBOOTSTRAPPED_SHAPES
from test.describe to test.describe.serial, preserving the existing suite body
and test structure.
- Around line 80-84: Update openProvidersPage to start page.waitForResponse
before navigating to /agent-network/providers, matching the GET
/api/agent-network/settings request with a timeout. Await that response after
navigation and before returning the page so assertions observe the rendered
state after the mocked settings response is consumed.
- Around line 115-116: Replace the page.getByText() assertions in the agent
network settings test, including the additional assertions at the referenced
later range, with page.getByTestId() using stable kebab-case IDs for the empty
state and bootstrapped endpoint. If those components lack test IDs, add optional
data-testid props and pass the corresponding IDs through their render paths.
- Around line 15-16: The agent-network spec should use the custom
dashboardAsOwner fixture instead of raw Browser/Page authentication. Update the
test setup and test signatures to inject dashboardAsOwner, remove the Browser
and loginToApp imports/usages, and relocate the owner.json feature-flag setup
into the fixture lifecycle while preserving the existing test behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 52cbb84a-0ed6-46b3-b919-be8c83e22e4c

📥 Commits

Reviewing files that changed from the base of the PR and between b66cc4c and f73cf5b.

📒 Files selected for processing (2)
  • e2e/tests/agent-network-settings-shapes.spec.ts
  • src/modules/agent-network/AIProvidersProvider.tsx

Comment thread e2e/tests/agent-network-settings-shapes.spec.ts Outdated
Comment thread src/modules/agent-network/AIProvidersProvider.tsx Outdated
useFetchApi keeps the previous SWR data alongside the error, so a later
404 could expose stale settings through the memo; it now yields null
when the error is a 404 while still riding out transient failures on
the kept data. The wire-shapes spec closes its browser context when a
setup step throws before the close callback is handed to the test.
@mlsmaycon
mlsmaycon marked this pull request as ready for review August 3, 2026 16:21
@mlsmaycon
mlsmaycon merged commit 19d82cc into main Aug 3, 2026
8 of 9 checks passed
@mlsmaycon
mlsmaycon deleted the agent-network-settings-defaults branch August 3, 2026 23:59
ocoj pushed a commit to ocoj/dashboard that referenced this pull request Aug 16, 2026
* Handle agent-network settings defaults response

The management API now answers the settings GET with a defaults object
before the account is bootstrapped (empty cluster/subdomain/endpoint)
instead of a JSON null body. Normalize that shape to the existing null
settings signal so every consumer keeps a single not-bootstrapped check,
while still tolerating the null body and 404 from older backends.

* Pin the settings wire-shape normalization in a Playwright spec

The providers page must render the connect-first empty state for every
unbootstrapped settings shape the management API has answered with over
time (defaults object with an empty endpoint, JSON null body, 404) and
the endpoint badge once bootstrapped. The settings route is mocked per
test so the spec is independent of the backend build and of account
state left behind by other suites.

* Address review: no stale settings on 404, close context on setup failure

useFetchApi keeps the previous SWR data alongside the error, so a later
404 could expose stale settings through the memo; it now yields null
when the error is a 404 while still riding out transient failures on
the kept data. The wire-shapes spec closes its browser context when a
setup step throws before the close callback is handed to the test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants