Fix "c(...) is not a function" on Firebase SSR deploy
A Stack Overflow question with 14 votes and no accepted answer, and the GitHub issue the same reporter filed a month later with minification turned off. Together they show exactly which import fails, and that this bug was never really fixed — only avoided.
The deploy that throws this error always works first with firebase serve:
Function failed on loading user code. Error message:
Code in file index.js can't be loaded. Is there a syntax error in your code?
Detailed stack trace: TypeError: c(...) is not a function
at Object.<anonymous> (/user_code/assets/app.server.js:1:28950)
at Object.module.exports.n (/user_code/assets/app.server.js:1:29283)
...
Functions deploy had errors.
To continue deploying other features (such as database), run:
firebase deploy --except functions
Error: Functions did not deploy properly.That is the exact text from the Stack Overflow question (14 votes, 1,268 views, no accepted answer, open since January 2019). c(...) is a minified identifier, so by itself it says almost nothing. What makes this report unusually easy to verify is that the same person filed a near-duplicate GitHub issue against the template they forked a month later, this time with minification turned off specifically to get a readable name.
Why it happens#
With minification disabled, the issue's stack trace reads:
TypeError: react_universal_component__WEBPACK_IMPORTED_MODULE_2___default(...) is not a function
at Object.<anonymous> (/user_code/assets/app.server.js:1525:128)
at Object.module.exports.hasOwnProperty (/user_code/assets/app.server.js:1547:30)
at __webpack_require__ (/user_code/assets/app.server.js:27:30)
at Object.<anonymous> (/user_code/assets/app.server.js:13330:26)
at __webpack_require__ (/user_code/assets/app.server.js:27:30)
at Object.<anonymous> (/user_code/assets/app.server.js:8001:18)
at __webpack_require__ (/user_code/assets/app.server.js:27:30)
at /user_code/assets/app.server.js:104:18
at Object.<anonymous> (/user_code/assets/app.server.js:107:10)
at Module._compile (module.js:577:32)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32)
at tryModuleLoad (module.js:453:12)
at Function.Module._load (module.js:445:3)
at Module.require (module.js:504:17)
at require (internal/module.js:20:19)The ___default suffix is what Babel's module interop produces for import ReactUniversalComponent from 'react-universal-component': the bundler renames the default binding to that longer symbol, calls it like a function, and minifies it down to c(...) for production. So the crash is a default export that is not callable, specifically inside the bundle Cloud Functions runs, for the react-universal-component package this SSR template used for route-level code splitting.
That points at the bundling step, not at the library. react-universal-component 3.0.3 — the latest stable release in January 2019, per its npm registry history — exports a plain Babel-compiled default (exports.default, Object.defineProperty(exports, "__esModule", { value: true })), the ordinary shape that require() interop handles without help. Requiring that exact version directly under plain Node, with no webpack and no Cloud Functions involved, and calling its default export the same way the compiled code does, raises no error:
typeof require(...) = object
typeof require(...).default = function
call result type: function
OK: default export is callable under plain Node require()(Reproduced locally in a throwaway node:18-alpine container, 31 October 2026, against react-universal-component@3.0.3 installed fresh — see repro.log in this draft's folder.) That negative control rules out the obvious suspect: the package's own CommonJS/ES module interop is intact. Whatever breaks the call happens only inside the specific webpack bundle that got uploaded as app.server.js, and neither reporter ever pinned it down further — the template's maintainer could only guess, in a comment on the issue, that the crash was "caused by dynamically importing a universal component."
The other half of the picture is how Firebase expects this to be wired at all. Firebase's Cloud Functions + Hosting docs describe Cloud Functions as code that runs "in response to HTTPS requests," connected to Hosting through a rewrite rule — not a function pointed at the same directory Hosting serves statically. The question's own firebase.json used the public directory as the Functions directory as well, which is exactly the setup the one constructive Stack Overflow answer flags: "you cannot serve static assets with cloud functions. You need a mix of firebase functions and firebase hosting." Mixing the two roles into one directory is consistent with a server bundle that does not contain what the build actually produced for the browser.
Fix#
Three things actually change the outcome, in the order the evidence supports them:
-
De-minify before guessing. If your deploy throws a single-letter identifier like
c(...), disable minification in the server webpack config (or setmode: 'development'for a one-off deploy) and redeploy. You will get the real symbol name — in this casereact_universal_component__WEBPACK_IMPORTED_MODULE_2___default— which tells you which dependency's default import is failing, instead of guessing from a letter. -
Separate Hosting's
publicdirectory from the Functions directory, wired by a rewrite. Infirebase.json:
{
"hosting": {
"public": "public",
"rewrites": [
{ "source": "**", "function": "ssrRender" }
]
},
"functions": {
"source": "functions"
}
}functions.source should point at a directory that only contains the Cloud Function's own code and its package.json — not the static assets Hosting already serves from public. This matches the structure in Firebase's walk-through for connecting a function to Hosting, and it is the gap the question's own firebase.json has (function directory = public).
-
Drop the dynamic import if the crash is in a code-splitting library. This is the only workaround either reporter confirmed worked: give up on route-level splitting through
react-universal-componentinside the Cloud Function bundle, render the component tree directly, and redeploy. It is not an elegant fix, but it is the one documented outcome: "I just moved all of my app to static deployment (with a index.html, no dynamic importing), works perfectly." -
For a project started today, skip the hand-built Functions+Hosting split for SSR altogether. Firebase's own hosting docs now say plainly: "If you are building server-rendered Angular or Next.js apps, check out next-generation Firebase App Hosting, a full-stack solution for modern web frameworks." App Hosting builds and runs the SSR server for you, instead of asking you to hand-roll the
rewrite+ Cloud Function wiring this question is fighting. If the project is Next.js specifically and doesn't need true SSR, Next.js's static export turnsnext buildinto plain HTML/CSS/JS that Hosting alone can serve — no Function, no bundle to break.
Verify the fix#
After separating public and functions.source, run firebase deploy --only functions on its own first: a clean deploy with no "Function failed on loading user code" means the Cloud Function's own bundle loaded correctly, before you add Hosting's rewrite back into the mix. Then deploy Hosting and load the site through its real domain, not firebase serve — this question's whole premise is that the two diverge, so only a deploy proves anything. If the crash returns, repeat step 1 (disable minification) and compare the new de-minified symbol against the dependency you just added or upgraded; a different package name in the trace means a different root cause, not the same unresolved bug.
If you migrate to Firebase App Hosting instead, verify by checking the Cloud Run-backed backend's build log in the Firebase console shows a successful SSR build step, rather than a Functions deploy log — App Hosting does not go through firebase deploy --only functions at all.
One email a month — the latest explained errors
What the site published that month — mostly Next.js, Supabase and Node errors, explained. You confirm by email; unsubscribe any time in one click.
When the symbol name differs#
The specific package in this report was react-universal-component, used for code-split route rendering. The same crash shape — a ___default(...) is not a function once de-minified — shows up with other default-exporting dependencies that behave differently between a local build and the bundle actually uploaded to a Cloud Function: a peerDependency resolved to two different copies in client and server builds, or a package with a browser field in its package.json that silently swaps implementations depending on the target. The fix in step 1 (turn off minification, read the real name) is the same regardless of which package it turns out to be; only step 3 or 4 changes with it.
The next error#
Getting the Functions deploy itself to succeed does not guarantee Hosting serves it at the right URL. If the next failure is Assertion failed: resolving hosting target of a site with no site name or target name, that is a different, documented firebase.json shape problem — see the fix for that assertion. And if the real goal is just a working Next.js deploy pipeline rather than a hand-wired Cloud Function, setting FIREBASE_CLI_EXPERIMENTS correctly in CI covers the framework-aware path Firebase offered before steering everyone to App Hosting.
Teams that give up on Firebase Functions for the SSR layer entirely usually move the renderer into a container they control instead, at which point the failure mode changes again — a standalone Next.js server missing its server.js entrypoint in Docker is the equivalent first error on that path.
None of the three sources behind this error — the Stack Overflow question, its GitHub duplicate, or Firebase's own docs — describe a committed fix inside the Cloud Functions bundling pipeline itself. Seven years on, the honest answer for anyone hitting this exact crash is still to de-minify, confirm which default export fails, and then choose between rewriting around it or moving off the pattern that triggers it, exactly as the original reporter eventually did.
Frequently Asked Questions
Still stuck? Paste your error.
Paste the error message or stack trace — we check it against every fix and tool on the site.
Continue Reading
Fix "Assertion failed: resolving hosting target" (Firebase)
firebase deploy says this "should have caused an error earlier". With a single hosting object and a dead login it did, and the CLI threw it away. Both causes, reproduced on firebase-tools 15.32.1, and how to tell them apart.
Fix npm ERESOLVE: Firebase prerelease peer conflict
Read the two version requirements behind this Firebase install failure, reproduce the prerelease mismatch, and select a stable dependency tree.
auth/popup-closed-by-user fires 8 s late: cause and fix
Your login button can come back to life a fraction of a second after the user closes the Google popup, without patching the SDK or breaking slow sign-ins.


