How to Fix: Failed to find server action/Cannot read properties of undefined (reading ‘workers’)

5 min read

The “Failed to find server action” error followed by “Cannot read properties of undefined (reading ‘workers’)” usually means your app is starting with a production build whose server action manifest and runtime expectations no longer match the actual server process. In the reproduced setup, the failure appears after building from the workspace root and then starting an individual app, which creates a mismatch in how Next.js server actions are discovered and loaded at runtime.

Understanding the Root Cause

This bug happens because server actions are compiled into a build-time manifest that Next.js uses to map an incoming action request back to the correct module and worker runtime. If you build in one context and start in another, especially inside a monorepo or workspace app, the running server may look for manifests, worker entries, or action references that do not exist where it expects them.

That is why two errors often appear together:

  • Failed to find server action means the action ID sent by the client cannot be resolved from the server’s compiled action manifest.
  • Cannot read properties of undefined (reading ‘workers’) means the runtime tries to read worker metadata for that action, but the underlying manifest entry is missing or undefined.

In practice, this is usually triggered by one or more of the following:

  • Building from the repository root but starting from a nested app with a different working directory.
  • Using a stale .next output generated before code or package layout changes.
  • Starting the app with a command that does not align with how the build artifacts were produced.
  • Cross-package imports that cause server action modules to be bundled differently between build and runtime.

In the linked reproduction, the important pattern is: build globally, start locally, then invoke a server action. That sequence can break the action lookup path when the app runtime does not fully match the build output that generated the action manifest.

Step-by-Step Solution

The fix is to make sure the build step and the start step happen in the same app context, with a clean output directory, so the generated server action manifest matches the server that is actually running.

1. Clean old build artifacts

Delete any stale Next.js output before rebuilding.

rm -rf apps/foo/.next
rm -rf .next

If your workspace tool creates additional caches, clear those too.

rm -rf node_modules/.cache

2. Install dependencies from the workspace root

yarn install

3. Build the target app from its own directory

Instead of relying on a root-level build that may produce artifacts with a different runtime context, build the app directly where it will be started.

cd apps/foo
yarn build

4. Start the same app from the same directory

yarn start

This ensures the server action manifest, route handlers, and worker metadata all come from the same build context.

5. Verify your server action file uses the correct pattern

Make sure the action is declared in a server context and imported in a supported way.

'use server'

export async function submitForm(formData: FormData) {
  // server-side logic
}

And in a component:

import { submitForm } from './actions'

export default function Page() {
  return (
    <form action={submitForm}>
      <button type="submit">Submit</button>
    </form>
  )
}

6. Avoid importing server actions through unstable cross-package boundaries

If the action lives in a shared workspace package, temporarily move it into the app itself to confirm whether the issue is caused by package boundary compilation.

apps/foo/app/actions.ts

If that fixes the issue, the root problem is likely how the shared package is being bundled during build versus runtime resolution.

7. Keep build and runtime commands consistent in monorepos

A safer pattern is to expose app-specific scripts at the root so both commands target the same workspace explicitly.

{
  "scripts": {
    "build:foo": "yarn workspace foo build",
    "start:foo": "yarn workspace foo start"
  }
}

Then run:

yarn build:foo
yarn start:foo

8. If the issue persists, rebuild from scratch

rm -rf node_modules
rm -rf apps/foo/.next
yarn install
cd apps/foo && yarn build && yarn start

This eliminates stale dependency state and outdated manifests.

The most reliable fix for this specific issue is:

rm -rf apps/foo/.next
cd apps/foo
yarn build
yarn start

If you previously built from the monorepo root, do not reuse that output for a nested app start unless your workspace tooling explicitly guarantees the same artifact layout.

Common Edge Cases

1. Shared package exports a server action

Server actions inside a shared package may compile differently from actions inside the app directory. If the runtime cannot map the action ID, move the action into the app first and retest.

2. Mixed Next.js versions across workspaces

If one package resolves a different Next.js version or related React dependency, build artifacts can become incompatible. Confirm that the workspace uses a single resolved version.

3. Client component imports a server-only module indirectly

If a client component pulls in code that eventually references a server action file incorrectly, the bundler may create invalid output. Keep client and server boundaries clean.

4. Stale deployment artifacts

If this happens only in production, your server may still be running an older build while the browser posts an action ID from a newer client bundle. Redeploy both together.

5. Custom start commands or nonstandard working directories

Some process managers start the app from a directory different from the one used during build. That can break manifest lookup. Ensure the runtime launches with the same app root.

FAQ

Why does this only fail after submitting the form?

The initial page can render fine because normal route rendering works, but the error only appears when the browser sends a server action request. That request depends on a valid action ID and manifest entry, which is where the mismatch is exposed.

Is this a coding bug in the action itself?

Usually no. This specific combination of errors is more often a build/runtime alignment problem than a logic bug inside the action function.

Can I keep building from the monorepo root?

Yes, but only if your workspace setup guarantees that the app you start uses the exact build artifacts generated for that app. If not, use explicit workspace build and start commands or run both commands inside the app directory.

The key takeaway is simple: server actions are build-artifact sensitive. When Next.js cannot find the generated action metadata, the request fails, and the runtime often falls through to the ‘workers’ undefined error. Build and start the same app in the same context, clear stale output, and keep server action files inside stable app boundaries whenever possible.

Leave a Reply

Your email address will not be published. Required fields are marked *