This Next.js error occurs when attempting to call revalidatePath outside of a Server Action or Route Handler context. The function requires server-side execution and cannot be used in Client Components or browser environments.
This error is thrown by Next.js when you attempt to call the revalidatePath function in an unsupported context. The revalidatePath function is a cache invalidation utility that can only be executed on the server, specifically within Server Actions (functions marked with "use server") or Route Handlers (API routes). Next.js enforces this restriction because revalidatePath interacts directly with the server-side cache and file system to purge cached pages and trigger regeneration. Client Components run in the browser and have no access to these server resources. Attempting to use revalidatePath in a Client Component, inline in a React component without proper server context, or in other client-side code will immediately trigger this error. The function signature is revalidatePath(path: string, type?: "page" | "layout"): void, where the path parameter can be either a route pattern like /product/[slug] or a specific URL like /product/123. Understanding where and how to properly invoke this function is essential for implementing on-demand revalidation in Next.js applications.
First, locate the exact file and function where the error occurs. Check if the code is in a Client Component (has "use client" directive) or lacks the "use server" directive. Look for:
// ❌ Wrong: Client Component
"use client"
import { revalidatePath } from "next/cache"
export default function MyComponent() {
const handleClick = () => {
revalidatePath("/posts") // Error!
}
return <button onClick={handleClick}>Refresh</button>
}Identify if revalidatePath is being called in event handlers, useEffect hooks, or directly in component render logic.
Extract the revalidatePath logic into a dedicated Server Action file with the "use server" directive:
// app/actions/revalidate.ts
"use server"
import { revalidatePath } from "next/cache"
export async function revalidatePostsAction() {
revalidatePath("/posts")
// Optionally return success status
return { success: true }
}Place this file in a dedicated actions directory (e.g., app/actions/) to keep Server Actions organized.
Now update your Client Component to call the Server Action instead:
// app/components/RefreshButton.tsx
"use client"
import { revalidatePostsAction } from "@/app/actions/revalidate"
export default function RefreshButton() {
const handleRefresh = async () => {
await revalidatePostsAction()
// Handle success/error
}
return <button onClick={handleRefresh}>Refresh Posts</button>
}Client Components can call Server Actions as regular async functions, and Next.js handles the server-client communication automatically.
If you're working within a Server Component, you can define an inline Server Action:
// app/posts/page.tsx (Server Component by default)
import { revalidatePath } from "next/cache"
export default function PostsPage() {
async function refreshPosts() {
"use server"
revalidatePath("/posts")
}
return (
<form action={refreshPosts}>
<button type="submit">Refresh</button>
</form>
)
}The "use server" directive can be placed inside the function for inline Server Actions within Server Components.
For data mutation workflows, call revalidatePath after updating data and before redirecting:
"use server"
import { revalidatePath } from "next/cache"
import { redirect } from "next/navigation"
export async function createPost(formData: FormData) {
const title = formData.get("title") as string
// Update database
await db.post.create({ data: { title } })
// Revalidate before redirect
revalidatePath("/posts")
revalidatePath("/posts/[slug]", "page")
redirect("/posts")
}This ensures the cache is invalidated before the user navigates to the updated page.
Alternatively, create a Route Handler for revalidation triggered by external webhooks or API calls:
// app/api/revalidate/route.ts
import { revalidatePath } from "next/cache"
import { NextRequest, NextResponse } from "next/server"
export async function POST(request: NextRequest) {
const { path } = await request.json()
try {
revalidatePath(path)
return NextResponse.json({ revalidated: true })
} catch (err) {
return NextResponse.json({ revalidated: false }, { status: 500 })
}
}Route Handlers support revalidatePath but mark paths for revalidation on the next visit rather than immediately updating the cache.
Ensure the "use server" directive is at the very top of the file (for file-level Server Actions) or immediately inside the function:
// ✅ Correct: File-level
"use server"
import { revalidatePath } from "next/cache"
export async function myAction() {
revalidatePath("/posts")
}
// ✅ Correct: Function-level
export async function myAction() {
"use server"
revalidatePath("/posts")
}
// ❌ Wrong: Directive in wrong place
import { revalidatePath } from "next/cache"
"use server" // Too late!The directive must appear before any imports or code execution.
In Server Functions (Server Actions), revalidatePath updates the UI immediately if the user is viewing the affected path, whereas in Route Handlers, it only marks the path for revalidation on the next visit. This behavioral difference is important for user experience considerations.
When using revalidatePath with dynamic routes, you can specify the type parameter: revalidatePath("/posts/[slug]", "page") revalidates all matching pages, while revalidatePath("/posts/[slug]", "layout") revalidates the layout and all nested pages. Omitting the type parameter defaults to "page".
There are known issues with revalidatePath in specific contexts: when called from Server Actions triggered by Intercepting Routes, it can break useFormStatus() and useFormState() hooks (Next.js issues #58772, #60950). Additionally, some users report that revalidatePath may not immediately revalidate paths and instead keep stale data until the default cache time expires or a hard refresh occurs (#50356).
For debugging revalidation issues, note that Next.js caching behavior differs between development and production. Always test revalidation in a production build (npm run build && npm start) to see actual cache invalidation behavior, as development mode may have different caching characteristics.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite