github →

Issue #21166

Bug: Home redirect always lands on first object alphabetically, ignores last-visited

draft pr open
bug easy95% confidencesonarly:mediumtype: bug

Description

Going to the workspace root (/) always redirects me to the same object: the first one alphabetically by nameSingular. It doesn't matter which object I visited last, and clearing browser cache/localStorage makes no difference. In my workspace a custom object called "Activities" (nameSingular: "activity") always wins because "a" sorts first.

Steps to reproduce

  1. Have multiple objects, with one that sorts first alphabetically by nameSingular.
  2. Visit a different object's index page, e.g. Companies.
  3. Go to the workspace root /.
  4. Expected: redirect to the last-visited object (Companies). Actual: redirect to the alphabetically-first object.

Root cause

useDefaultHomePagePath uses lastVisitedObjectMetadataItem if it's set, otherwise it falls back to the first of readableNonSystemObjectMetadataItems, which is sorted with a.nameSingular.localeCompare(b.nameSingular). The last-visited branch never fires, for two reasons.

First, lastVisitedObjectMetadataItemIdState is created via createAtomState({ useLocalStorage: true }), which calls atomWithStorage(key, default, undefined, undefined), so getOnInit is unset and defaults to false in jotai 2.x. The atom is only ever accessed imperatively through store.get/store.set and is never subscribed via a hook, so it never mounts or hydrates. On a fresh load store.get(...) returns the default null and the code falls through to the alphabetical fallback. Note that the useSessionStorage and useCookieStorage branches in the same factory do pass { getOnInit: true }, only the useLocalStorage branch doesn't.

Second, defaultHomePagePath is a useMemo that reads the atom imperatively and doesn't list it as a dependency, so it isn't reactive to in-session updates either.

Suggested fix

Pass { getOnInit: true } for the useLocalStorage branch in createAtomState, or for this atom specifically, so store.get returns the persisted value. Optionally have useDefaultHomePagePath subscribe to the atom (e.g. useAtomValue) and add it to the memo deps so it stays reactive. Worth adding a regression test that sets a last-visited id and asserts the redirect resolves to that object, since the current tests only cover the fallback.

Environment

  • Twenty main @ 6b5a956 (2026-06-02)
  • jotai ^2.17.1
Verification
Verified — checks passed

We installed dependencies and ran lint, typecheck, build, and test in a sandbox — all passed.

Likely addresses the issue (95% confidence)

An AI estimate of whether the change actually fixes the issue — the checks themselves only confirm nothing broke. It's a hint for review, not a pass/fail check.

Why?

The diff fixes both root causes identified in the issue: it adds `getOnInit: true` to the `useLocalStorage` branch in `createAtomState.ts` so `lastVisitedObjectMetadataItemIdState` hydrates on init, and changes `useDefaultHomePagePath.ts` to read that atom reactively via `useAtomStateValue` instead of `store.get`, also adding it to the `useCallback` dependencies so the redirect updates when the value changes. A regression test verifies the last-visited redirect behavior works.

  • lintpassed · 24.3s
     NX   Running target lint for project twenty-front and 3 tasks it depends on:
    
    - twenty-front
    
    
    
    > nx run twenty-shared:generateBarrels  [local cache]
    
    > tsx packages/twenty-shared/scripts/generateBarrels.ts
    
    
    > nx run twenty-oxlint-rules:build  [local cache]
    
    > npx esbuild packages/twenty-oxlint-rules/oxlint-plugin.ts --bundle --format=esm --platform=node --outfile=packages/twenty-oxlint-rules/dist/oxlint-plugin.mjs "--define:__filename='\"[plugin]\"'" "--define:__dirname='\"[plugin]\"'" "--banner:js=import { createRequire } from 'module'; const require = createRequire(import.meta.url);"
    
    npm warn Unknown env config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    
      packages/twenty-oxlint-rules/dist/oxlint-plugin.mjs  251.0kb
    
    ⚡ Done in 30ms
    
    > nx run twenty-shared:build  [local cache]
    
    > npx vite build
    
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    > tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --noEmit false --outDir dist --rootDir src && npx tsc-alias -p tsconfig.lib.json --outDir dist
    
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    
    > nx run twenty-front:lint
    
    > npx oxlint --type-aware -c .oxlintrc.json src/ && (npx oxfmt --check src/ || (echo 'ERROR: oxfmt formatting check failed! Fix with: npx nx lint twenty-front --configuration=fix' && false))
    
    npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    Found 0 warnings and 0 errors.
    Finished in 17.3s on 7480 files with 29 rules using 3 threads.
    npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    Checking formatting...
    
    All matched files use the correct format.
    Finished in 2867ms on 7749 files using 3 threads.
    
    
    
     NX   Successfully ran target lint for project twenty-front and 3 tasks it depends on
    
    Nx read the output from the cache instead of running the command for 3 out of 4 tasks.
  • typecheckpassed · 81.6s
    .ts' 'dist/utils/**/*.d.ts.map' && npx rollup -c rollup.config.sdk-dts.mjs
    
    npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    
    src/sdk/define/index.ts → dist/define/index.d.ts...
    created dist/define/index.d.ts in 2.9s
    
    src/sdk/front-component/index.ts → dist/front-component/index.d.ts...
    created dist/front-component/index.d.ts in 1.4s
    
    src/sdk/billing/index.ts → dist/billing/index.d.ts...
    created dist/billing/index.d.ts in 941ms
    
    src/sdk/logic-function/index.ts → dist/logic-function/index.d.ts...
    created dist/logic-function/index.d.ts in 1.4s
    
    src/sdk/utils/index.ts → dist/utils/index.d.ts...
    created dist/utils/index.d.ts in 789ms
    
    > nx run twenty-front-component-renderer:build
    
    > npx rimraf dist && npx vite build -c vite.config.ts
    
    npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    > tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --noEmit false --outDir dist --rootDir src && npx tsc-alias -p tsconfig.lib.json --outDir dist
    
    npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "dangerously-allow-all-builds". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    npm warn Unknown user config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
    
    > nx run twenty-front:typecheck
    
    > tsgo -p tsconfig.json
    
    
    
    
     NX   Successfully ran target typecheck for project twenty-front and 8 tasks it depends on
    
    Nx read the output from the cache instead of running the command for 5 out of 9 tasks.
  • buildpassed · 141.4s
      429.34 kB │ gzip:   143.43 kB
    build/assets/native-48B9X9Wg.js                                                      432.75 kB │ gzip:    82.80 kB
    build/assets/blocknote-uAyHRr_h.js                                                   433.64 kB │ gzip:   131.02 kB
    build/assets/SpreadsheetImport-CVEh_ndi.js                                           444.33 kB │ gzip:   152.40 kB
    build/assets/Inter_18pt-Regular-byxnNS-8-BnplJFJY.js                                 456.96 kB │ gzip:   204.79 kB
    build/assets/Inter_18pt-Bold-BOnnSImi-hPpeqQwn.js                                    458.93 kB │ gzip:   208.13 kB
    build/assets/Inter_18pt-Italic-BVnfHlUD-BNrjkzHH.js                                  462.03 kB │ gzip:   212.52 kB
    build/assets/Inter_18pt-BoldItalic-DPKIpVzB-SGWoqiFX.js                              464.29 kB │ gzip:   216.29 kB
    build/assets/DocumentViewer-ypWTPoYb.js                                              534.31 kB │ gzip:   170.27 kB
    build/assets/SettingsGraphQLPlayground-CmhTY-Gg.js                                   652.36 kB │ gzip:   207.56 kB
    build/assets/FrontComponentRenderer-DLjVfkB-.js                                    1,019.01 kB │ gzip:   242.09 kB
    build/assets/AllIcons-B093-FjO-YZocWUPU.js                                         1,305.19 kB │ gzip:   243.12 kB
    build/assets/exportBlockNoteEditorToPdf-DqGPSCBM.js                                1,504.68 kB │ gzip:   501.77 kB
    build/assets/index-D33Oq4y8.js                                                     2,217.74 kB │ gzip:   636.39 kB
    build/assets/index-BaVvKbEl.js                                                     3,340.57 kB │ gzip:   861.14 kB
    build/assets/get-function-input-schema-DTlcRJz3-BuUwaHjC.js                        3,593.27 kB │ gzip: 1,029.77 kB
    build/assets/index-DVvTod4c.js                                                     6,255.95 kB │ gzip: 1,722.76 kB
    ✓ built in 2m 13s
    
    [linaria/wyw] ===== CSS PRE-BUILD SUMMARY =====
    [linaria/wyw] Files transformed: 1016
    [linaria/wyw] Files skipped (no @linaria): 15664
    [linaria/wyw] Transform time: 30839ms
    [linaria/wyw] Avg per transformed file: 30.4ms
    [linaria/wyw] Slow files (>10x avg = 304ms):
    [linaria/wyw]   774ms /src/modules/layout-customization/components/LayoutCustomizationBarMenuDropdown.tsx
    [linaria/wyw]   763ms /src/modules/layout-customization/components/LayoutCustomizationBar.tsx
    [linaria/wyw]   410ms /src/modules/error-handler/components/AppRootErrorFallback.tsx
    [linaria/wyw]   338ms /src/modules/object-record/record-table/record-table-body/components/RecordTableBodyVirtualizedDraggableClone.tsx
    [linaria/wyw]   312ms /src/modules/command-menu/components/CommandMenuOpenContainer.tsx
    [linaria/wyw] ==========================================
    
    
    
    
     NX   Successfully ran target build for project twenty-front and 8 tasks it depends on
    
    Nx read the output from the cache instead of running the command for 8 out of 9 tasks.
  • testpassed · 219.6s
    0m twenty-front  packages/twenty-front/src/modules/captcha/utils/__tests__/getCaptchaUrlByProvider.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/side-panel/pages/page-layout/utils/__tests__/getSortLabelSuffixForFieldType.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/combineFilters.test.ts
     PASS   twenty-front  packages/twenty-front/src/utils/__tests__/sleep.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/page-layout/widgets/graph/utils/__tests__/getMaxLabelLength.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/localization/utils/detection/__tests__/detectTimeFormat.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/ui/utilities/hotkey/hooks/__tests__/useGoToHotkeys.test.tsx
     PASS   twenty-front  packages/twenty-front/src/modules/workflow/workflow-trigger/utils/__tests__/getTriggerIcon.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/object-record/record-table/empty-state/utils/__tests__/getEmptyStateSubTitle.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/activities/files/utils/__tests__/downloadFile.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/object-record/utils/__tests__/filterAvailableTableColumns.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuOnItemClick.test.tsx
     PASS   twenty-front  packages/twenty-front/src/modules/ui/utilities/drag-select/hooks/__tests__/useDragSelect.test.tsx
     PASS   twenty-front  packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/http-request-action/utils/__tests__/isMethodWithBody.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/settings/developers/utils/__tests__/computeNewExpirationDate.test.ts
     PASS   twenty-front  packages/twenty-front/src/utils/__tests__/parseApolloStoreFieldName.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/object-record/utils/__tests__/getUpdatedFieldsFromRecordInput.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.test.ts
     PASS   twenty-front  packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.test.ts
     PASS   twenty-front  packages/twenty-front/src/utils/validation-schemas/__te

Ran 6/8/2026, 11:20:02 PM · yarn

Get the code

Pull this branch
With gh CLI
gh pr checkout 13 --repo kamransiddiqui/twenty
Raw git
git fetch https://github.com/kamransiddiqui/twenty.git gitgot/issue-21166
git checkout -b gitgot/issue-21166 FETCH_HEAD

Fork-mode request: the branch lives on kamransiddiqui/twenty (your fork), not twentyhq/twenty, so the commands above target the fork.

Drive locally

Paste this into your local coding agent (Claude Code, Cursor, etc.) to continue iterating with full repo context.

Context prompt
You are continuing work on a draft PR for twentyhq/twenty, addressing issue #21166.

First, check out the branch with gitgot's first-pass change (run from a clone of the repo):
  gh pr checkout 13 --repo kamransiddiqui/twenty

Then review the diff and:
- run the project's lint/typecheck/test commands and fix anything broken
- if the diff is wrong-headed, revert it and start fresh from the issue
- keep the change tight; do not refactor unrelated code
PR thread
  • No comments on the PR yet. Use the form below to start the thread.