How to fix Callable Functions: INTERNAL - Unhandled exception in Firebase

FirebaseINTERMEDIATEHIGHUpdated Dec 29, 2025· 182 views

This error indicates your Firebase Cloud Function threw an unhandled exception. It happens when your code crashes without proper error handling, preventing the function from returning a valid response to the client.

Quick fix

Fixes INTERNAL

import * as functions from "firebase-functions";

export const myFunction = functions.https.onCall(async (data, context) => {
  try {
    // Your function logic here
    const result = await someAsyncOperation(data);
    return { success: true, data: result };
  } catch (error) {
    console.error("Error in myFunction:", error);
    throw new functions.https.HttpsError(
      "internal",
      "An error occurred processing your request"
    );
  }
});
  1. Check Firebase Cloud Functions logs
  2. Wrap your function logic in try-catch
  3. Ensure all async operations are awaited
  4. Validate inputs before processing
firebase — error
import * as functions from "firebase-functions";
export const myFunction = functions.https.onCall(async (data, context) => {
try {
// Your function logic here
const result = await someAsyncOperation(data);
return { success: true, data: result };
} catch (error) {
console.error("Error in myFunction:", error);
throw new functions.https.HttpsError(
"internal",
"An error occurred processing your request"
);
}
});
Callable Functions: INTERNAL - Unhandled exception

What this error means

When a Firebase callable function encounters an unhandled exception—whether from a failed database query, network timeout, syntax error, or uncaught promise rejection—Firebase returns an "INTERNAL - Unhandled exception" error to the client instead of your custom error. Callable functions must complete successfully or explicitly throw an HttpsError. Any other exception, including uncaught promise rejections and async errors, results in this generic error. This makes debugging difficult because the actual error message is hidden from the client and only visible in your Firebase Cloud Functions logs.

Typical symptoms

  • Client receives 'INTERNAL - Unhandled exception' error when calling a Cloud Function
  • Function works locally in the emulator but fails in production
  • Error appears on the client but no clear message about what went wrong
  • Firebase Console shows the function invocation in the logs but the response is incomplete

Common causes

  1. Unhandled promise rejection or missing await keyword in async code
  2. Database query or API call fails without a try-catch block
  3. Throwing a regular Error instead of HttpsError from the function
  4. Code path throws an exception before the function returns a value
  5. Third-party library or SDK throws an error that isn't caught
  6. Using HttpsError with onRequest (HTTP trigger) instead of onCall (callable trigger)

How to fix "Callable Functions: INTERNAL - Unhandled exception"

1Check Firebase Cloud Functions logs

Open the Firebase Console and navigate to Functions > Logs to see the actual error message.

1. Go to https://console.firebase.google.com
2. Select your project
3. Click "Functions" in the left sidebar
4. Click the "Logs" tab
5. Find your function call and expand it to see the full error

The actual error will be more specific than "INTERNAL - Unhandled exception". Make note of the exact error type and message—this tells you what's actually failing in your code.

2Wrap your function logic in try-catch

The most common cause is missing error handling. Every callable function should catch errors and throw HttpsError:

typescript
import * as functions from "firebase-functions";

export const myFunction = functions.https.onCall(async (data, context) => {
  try {
    // Your function logic here
    const result = await someAsyncOperation(data);
    return { success: true, data: result };
  } catch (error) {
    console.error("Error in myFunction:", error);
    throw new functions.https.HttpsError(
      "internal",
      "An error occurred processing your request"
    );
  }
});

This catches any exception and converts it to a proper HttpsError that the client can handle.

3Ensure all async operations are awaited

Unhandled promise rejections are a common cause. Make sure you await all promises:

typescript
// WRONG - Promise not awaited
export const myFunction = functions.https.onCall(async (data, context) => {
  someAsyncFunction(); // Missing await
  return { success: true };
});

// CORRECT - Promise is awaited
export const myFunction = functions.https.onCall(async (data, context) => {
  await someAsyncFunction(); // Properly awaited
  return { success: true };
});

If a promise rejects and isn't awaited, the function exits before catching the error, resulting in the INTERNAL error.

4Validate inputs before processing

Throw an HttpsError immediately if inputs are invalid:

typescript
export const myFunction = functions.https.onCall(async (data, context) => {
  try {
    // Validate inputs first
    if (!data.userId) {
      throw new functions.https.HttpsError(
        "invalid-argument",
        "userId is required"
      );
    }

    if (!context.auth) {
      throw new functions.https.HttpsError(
        "unauthenticated",
        "You must be logged in"
      );
    }

    // Then process
    const result = await processUser(data.userId);
    return { success: true, data: result };
  } catch (error) {
    if (error instanceof functions.https.HttpsError) {
      throw error; // Re-throw HttpsError
    }
    console.error("Unexpected error:", error);
    throw new functions.https.HttpsError("internal", "An error occurred");
  }
});
5Use proper error reporting

Log errors to both Cloud Logging and Error Reporting:

typescript
import { logger } from "firebase-functions";

export const myFunction = functions.https.onCall(async (data, context) => {
  try {
    // Function logic
  } catch (error) {
    // Log to Cloud Logging and Error Reporting
    logger.error("Error in myFunction", {
      error: error instanceof Error ? error.message : String(error),
      stack: error instanceof Error ? error.stack : undefined,
    });
    throw new functions.https.HttpsError(
      "internal",
      "An error occurred processing your request"
    );
  }
});

This makes debugging easier because you can see detailed error information in the Firebase Console logs.

6Test locally with the Firebase Emulator

The emulator helps catch errors before deployment:

bash
# Initialize emulator (if not already done)
firebase init emulators

# Start the emulator
firebase emulators:start --only functions

# In another terminal, test your function locally
firebase functions:shell
myFunction({userId: "123"})

The emulator shows you the actual error instead of the generic "INTERNAL" error, making it much easier to debug.

Advanced notes

Promise rejection chains: Be careful with promise chains. A rejected promise anywhere in the chain that isn't caught will cause an unhandled exception. Use .catch() or await/try-catch for all promises.

Firebase Admin SDK errors: When using the Firebase Admin SDK (Firestore, Realtime Database, Authentication), always wrap those calls in try-catch. Admin SDK operations can fail for permissions, network, or data validation reasons.

Network timeouts: External API calls or database queries that timeout without proper error handling will trigger this error. Set reasonable timeouts and catch timeout errors explicitly.

Serialization issues: Callable functions must return JSON-serializable data. Returning Firestore DocumentReferences, Date objects without conversion, or circular objects will cause serialization errors. Convert these to primitives before returning:

typescript
// WRONG - Firestore document not serializable
return { doc: firestoreDoc };

// CORRECT - Extract data and convert to primitive
return { data: firestoreDoc.data(), timestamp: firestoreDoc.get('createdAt').toMillis() };

HTTP triggers vs callable: If you're using onRequest (HTTP trigger) instead of onCall, throwing HttpsError won't properly serialize. Always use onCall for client SDKs, or handle HTTP responses manually for onRequest.

Frequently asked questions

What does "INTERNAL" mean?
When a Firebase callable function encounters an unhandled exception—whether from a failed database query, network timeout, syntax error, or uncaught promise rejection—Firebase returns an "INTERNAL - Unhandled exception" error to the client instead of your custom error. Callable functions must complete successfully or explicitly throw an HttpsError. Any other exception, including uncaught promise rejections and async errors, results in this generic error.
How do I fix "INTERNAL"?
This error indicates your Firebase Cloud Function threw an unhandled exception. It happens when your code crashes without proper error handling, preventing the function from returning a valid response to the client.
What causes "INTERNAL"?
Unhandled promise rejection or missing await keyword in async code Database query or API call fails without a try-catch block Throwing a regular Error instead of HttpsError from the function
Is the "INTERNAL" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading