T
TanStack•9mo ago
equal-aqua

Invariant failed useMatch

Hello, I don't exactly why but sometime, when I click on a <Link><Link>, I have Invariant failed which appear.
Error: Invariant failed
at invariant (tiny-invariant.js:8:15)
at Object.select (useMatch.js:14:7)
at useRouterState.js:21:19
at a3 (with-selector.production.min.js:11:204)
at with-selector.production.min.js:11:420
at Object.useSyncExternalStore (react-dom.production.min.js:178:368)
at react_production_min.useSyncExternalStore (react.production.min.js:26:309)
at withSelector_production_min.useSyncExternalStoreWithSelector (with-selector.production.min.js:11:489)
at useStore$1 (index.js:4:49)
at useRouterState (useRouterState.js:11:10)
Error: Invariant failed
at invariant (tiny-invariant.js:8:15)
at Object.select (useMatch.js:14:7)
at useRouterState.js:21:19
at a3 (with-selector.production.min.js:11:204)
at with-selector.production.min.js:11:420
at Object.useSyncExternalStore (react-dom.production.min.js:178:368)
at react_production_min.useSyncExternalStore (react.production.min.js:26:309)
at withSelector_production_min.useSyncExternalStoreWithSelector (with-selector.production.min.js:11:489)
at useStore$1 (index.js:4:49)
at useRouterState (useRouterState.js:11:10)
When I add a breakpoint, The error is 'could not find a nearest match' My current setup for these routes are: When I click on /routeA/$id, I fetch the entity and sub entity in the loader and then I throw a redirect to /route/$id/sub/$subId
10 Replies
national-gold
national-gold•9mo ago
this might be a known bug does this go away when you set from in the Link?
equal-aqua
equal-aquaOP•9mo ago
I have to put the route.fullPath from /route/$id/sub/$subId in from field ?
national-gold
national-gold•9mo ago
would need a minimal example. but in general it should be the route where that link is rendered on
equal-aqua
equal-aquaOP•9mo ago
The Link are in a global sidebar so the from field is updated a lot depending where the user is
const retailLinkOptions = linkOptions({
to: '/retails/$retailId',
// from: '/retails/$retailId',
activeProps: {
'data-active': true,
},
params: {
retailId: retail.id,
},
preload: false,
});
const retailLinkOptions = linkOptions({
to: '/retails/$retailId',
// from: '/retails/$retailId',
activeProps: {
'data-active': true,
},
params: {
retailId: retail.id,
},
preload: false,
});
export const Route = createFileRoute('/_dashboard/retails/$retailId')({
component: RouteComponent,
staleTime: 10_000,
loader: async ({ params, location, context }) => {
const retail = await context.queryClient
.ensureQueryData(getRetailQueryOptions(params.retailId))
.catch((error) => {
if (error instanceof HTTPException && error.status === 404) {
throw notFound()
}

throw error
})

const isOnProductPage = /\/retails\/[^/]+\/products\//g.test(
location.pathname,
)

const product = retail.products.at(0)

if (!isOnProductPage && product) {
throw redirect({
to: productRoute.to,
params: {
retailId: retail.id,
productId: product.id,
},
})
}

await context.queryClient.ensureQueryData(
listProductsFromRetailQueryOptions(params.retailId),
)

return retail
},
})
export const Route = createFileRoute('/_dashboard/retails/$retailId')({
component: RouteComponent,
staleTime: 10_000,
loader: async ({ params, location, context }) => {
const retail = await context.queryClient
.ensureQueryData(getRetailQueryOptions(params.retailId))
.catch((error) => {
if (error instanceof HTTPException && error.status === 404) {
throw notFound()
}

throw error
})

const isOnProductPage = /\/retails\/[^/]+\/products\//g.test(
location.pathname,
)

const product = retail.products.at(0)

if (!isOnProductPage && product) {
throw redirect({
to: productRoute.to,
params: {
retailId: retail.id,
productId: product.id,
},
})
}

await context.queryClient.ensureQueryData(
listProductsFromRetailQueryOptions(params.retailId),
)

return retail
},
})
national-gold
national-gold•9mo ago
I will look into this
equal-aqua
equal-aquaOP•9mo ago
Invariant failed: Could not find an active match from "/_dashboard/retails/$retailId/product/$productId" And here my route at product level
export const Route = createFileRoute('/_dashboard/retails/$retailId/products/$productId')({
component: RouteComponent,
validateSearch: (search): { version?: `ver_${string}` | undefined } => ({
version: search.version as `ver_${string}` | undefined,
}),
loaderDeps: ({ search: { version } }) => ({ version }),
loader: async ({ params, deps, context }) => {
const product = await context.queryClient.ensureQueryData(
getproductQueryOptions(params.productId),
);

const firstVersion = product.versions.sort((a, b) => a.createdAt - b.createdAt).at(0);

const isInproduct = product.versions.some((version) => version.id === deps.version);

if ((!deps.version || !isInproduct) && firstVersion) {
throw redirect({
to: '/retails/$retailId/products/$productId',
from: '/retails/$retailId/products/$productId',
params,
search: {
version: firstVersion.id,
},
});
}

return creative;
},
});
export const Route = createFileRoute('/_dashboard/retails/$retailId/products/$productId')({
component: RouteComponent,
validateSearch: (search): { version?: `ver_${string}` | undefined } => ({
version: search.version as `ver_${string}` | undefined,
}),
loaderDeps: ({ search: { version } }) => ({ version }),
loader: async ({ params, deps, context }) => {
const product = await context.queryClient.ensureQueryData(
getproductQueryOptions(params.productId),
);

const firstVersion = product.versions.sort((a, b) => a.createdAt - b.createdAt).at(0);

const isInproduct = product.versions.some((version) => version.id === deps.version);

if ((!deps.version || !isInproduct) && firstVersion) {
throw redirect({
to: '/retails/$retailId/products/$productId',
from: '/retails/$retailId/products/$productId',
params,
search: {
version: firstVersion.id,
},
});
}

return creative;
},
});
I have added from everytime where I redirect but it not work
national-gold
national-gold•9mo ago
no you cannot use the same value as to it must be a currently rendered route but it's only required when you use relative paths i know where to investigate, will get back to you
equal-aqua
equal-aquaOP•9mo ago
Ok Thanks a lot I found the solution 🎉 I used a route.useParams() in a sidebar but I think sometime, the route was not the current route pattern so that why a error was throwed
national-gold
national-gold•9mo ago
oh that's a completely different thing than I thought then 🤪 useParams({strict:false}) comes in handy here
equal-aqua
equal-aquaOP•9mo ago
oh yes ! thank you so much for your help

Did you find this page helpful?