# How to Troubleshoot Open-SEO Errors: A Complete Developer Guide

> Troubleshoot Open-SEO errors effectively with this developer guide. Learn to identify validation, configuration, and upstream issues by checking the code property for clear insights.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-08-02

---

**Open-SEO normalizes every server-side exception into a typed error code through a layered middleware pipeline, enabling you to distinguish between validation issues, configuration mistakes, and upstream failures by checking the `code` property returned to the client.**

Open-SEO runs as a Cloudflare Worker (or Docker container in self-hosted mode) and implements a strict error-handling architecture that converts raw exceptions into predictable, client-safe responses. Understanding this pipeline allows you to quickly pinpoint whether an error stems from user input, missing environment variables, or external API failures. This guide walks you through the complete error flow, common failure categories, and the exact source files you need to examine when troubleshooting.

## Understanding the Open-SEO Error Handling Pipeline

The error resolution process follows a strict sequence from request entry to client response. Each layer adds context while stripping sensitive internal details.

### Request Entry and Middleware Wrapping

All HTTP requests enter through [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) at the `fetch` function, which routes traffic to API endpoints, MCP handlers, or chat agents. Immediately after routing, the `errorHandlingMiddleware` (defined in [`src/middleware/errorHandling.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/errorHandling.ts)) wraps every server function execution. This middleware serves as the central catch-all that intercepts any thrown value, distinguishes validator errors from business-logic failures, logs the stack trace, and forwards a sanitized error to the client.

### AppError Normalization and Code Classification

When the middleware catches an exception, it normalizes the error into an `AppError` object defined in [`src/server/lib/errors.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/errors.ts). These objects carry a typed `code` property drawn from the canonical list in [`src/shared/error-codes.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/error-codes.ts). Available codes include `VALIDATION_ERROR`, `AUTH_CONFIG_MISSING`, `RATE_LIMITED`, `UPSTREAM_UNAVAILABLE`, and `INTERNAL_ERROR`. The `AppError` constructor ensures every error has a machine-readable identifier that persists across the server-client boundary.

### Client-Safe Transformation and Telemetry

Before reaching the client, the `toClientError` function (also in [`src/server/lib/errors.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/errors.ts)) strips internal details unless the code appears in `CLIENT_DETAIL_ERROR_CODES` (currently only `AUTH_CONFIG_MISSING`). For reportable errors—determined by `shouldCaptureAppErrorCode`—the middleware invokes `captureServerError` in [`src/server/lib/posthog.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/posthog.ts) to record the incident in PostHog or your configured analytics provider. Validation errors are intentionally excluded from telemetry to reduce noise. The middleware simultaneously outputs the stack trace via `console.error`, accessible via `wrangler tail` for Cloudflare deployments or `docker logs` for self-hosted instances.

## Common Open-SEO Error Categories and Diagnostic Steps

Understanding the five primary error categories helps you apply the correct fix without unnecessary debugging.

**Validation Errors** (`VALIDATION_ERROR`): These occur when user input fails schema checks, such as missing domains or malformed URLs. The codebase throws these in [`src/server/lib/domainUtils.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/domainUtils.ts) (via `normalizeDomainInput`) and various feature service files. To resolve, verify the request payload matches the expected schema and use the client helper `getErrorCode` to display friendly messages.

**Auth Configuration Errors** (`AUTH_CONFIG_MISSING`): This code indicates missing or incorrect environment variables like `TEAM_DOMAIN`, `CLOUDFLARE_ACCESS_TOKEN`, or Better-Auth settings. Originating in [`src/middleware/ensure-user/cloudflareAccess.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/ensure-user/cloudflareAccess.ts) and [`src/server/mcp/oauth-provider.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-provider.ts), these errors expose detailed messages to the client (unlike other codes). Check your `.env.*` files against [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md) to ensure all required keys are present.

**Rate Limiting and Quota Errors** (`RATE_LIMITED`, `INSUFFICIENT_CREDITS`): These surface when DataForSEO quotas exhaust or Cloudflare rate-limits trigger. The DataForSEO client in [`src/server/lib/dataforseo/client.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseo/client.ts) emits these codes. Review your DataForSEO usage dashboard to confirm credit availability, or implement throttling to reduce request frequency.

**Upstream Failures** (`UPSTREAM_UNAVAILABLE`, `DATAFORSEO_AUTH_FAILED`): When the DataForSEO API is down or authentication fails, these codes appear. Verify your `DATAFORSEO_API_KEY` is the base64-encoded string of `login:password` and test the endpoint with a direct curl command to isolate connectivity issues.

**Internal Server Errors** (`INTERNAL_ERROR`): Uncaught exceptions or bugs in business logic trigger this catch-all code. Any file throwing generic errors outside the `AppError` classification will result in this response. Check the stack trace in Cloudflare or Docker logs to locate the originating file, then wrap the suspect code in `try/catch` blocks to improve error handling.

## Step-by-Step Troubleshooting Workflow for Open-SEO

Follow this systematic approach to resolve errors efficiently:

1.  **Capture the error code on the client**: Import `getErrorCode` and `getStandardErrorMessage` from `@/client/lib/error-messages.ts` to extract the machine-readable identifier and user-friendly description from the caught error.

2.  **Check runtime logs**: For Cloudflare Workers, execute `wrangler tail` and search for lines containing `server.function error:`. For Docker deployments, run `docker logs <container>` to view the same `console.error` output from the middleware.

3.  **Locate the throwing code**: Use grep to search the repository for the specific error code, such as `grep -R "new AppError(\"VALIDATION_ERROR\""`. Common entry points include [`src/server/lib/domainUtils.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/domainUtils.ts), [`src/server/lib/dataforseo/client.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseo/client.ts), and feature service files in `src/server/features/*/services/*.ts`.

4.  **Validate the request payload**: Ensure required fields are present before the code reaches DataForSEO API calls. Many `VALIDATION_ERROR` instances originate in domain normalization checks that reject malformed hosts.

5.  **Fix configuration issues**: For `AUTH_CONFIG_MISSING`, verify environment variables including `TEAM_DOMAIN`, `CLOUDFLARE_ACCESS_TOKEN`, and `CLOUDFLARE_TURNSTILE_SITE_KEY` against the self-hosting documentation.

6.  **Confirm upstream health**: When encountering `UPSTREAM_UNAVAILABLE`, check the DataForSEO status page and validate your API credentials with a direct HTTP request to their endpoint.

7.  **Rerun and verify**: After applying fixes, repeat step one. If the client receives a successful response without throwing, the issue is resolved.

## Code Examples for Handling Open-SEO Errors

### Client-Side Error Handling Pattern

Use this pattern in your frontend to gracefully handle Open-SEO failures:

```typescript
import { getErrorCode, getStandardErrorMessage } from "@/client/lib/error-messages";

async function runAudit(projectId: string) {
  try {
    const resp = await fetch(`/api/audit?projectId=${projectId}`);
    if (!resp.ok) throw await resp.json();
    // Handle successful audit start...
  } catch (e) {
    const code = getErrorCode(e);
    alert(getStandardErrorMessage(e));
    console.debug("Audit start failed – code:", code);
  }
}

```

### Server-Side Validation Wrapper

Implement consistent validation by throwing `AppError` instances:

```typescript
import { AppError } from "@/server/lib/errors";

export function validateDomain(input: string) {
  if (!input) {
    throw new AppError("VALIDATION_ERROR", "Domain is required");
  }
  // Additional validation logic...
}

```

### Adding a Custom Error Code

Extend the error system for domain-specific failures:

1.  Add the code to [`src/shared/error-codes.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/error-codes.ts):

```typescript
"MY_NEW_CODE",

```

2.  Add the user-facing message to [`src/client/lib/error-messages.ts`](https://github.com/every-app/open-seo/blob/main/src/client/lib/error-messages.ts):

```typescript
MY_NEW_CODE: "Something specific went wrong – please contact support.",

```

3.  Throw the error in your server logic:

```typescript
throw new AppError("MY_NEW_CODE", "Details...");

```

## Summary

-   Open-SEO uses a centralized `errorHandlingMiddleware` in [`src/middleware/errorHandling.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/errorHandling.ts) to catch and normalize all exceptions.
-   Errors are classified using typed codes defined in [`src/shared/error-codes.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/error-codes.ts) and transported via the `AppError` class in [`src/server/lib/errors.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/errors.ts).
-   Client-side utilities in [`src/client/lib/error-messages.ts`](https://github.com/every-app/open-seo/blob/main/src/client/lib/error-messages.ts) translate codes into user-friendly messages.
-   Validation errors typically originate in [`src/server/lib/domainUtils.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/domainUtils.ts), while auth errors stem from [`src/middleware/ensure-user/cloudflareAccess.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/ensure-user/cloudflareAccess.ts).
-   View detailed stack traces using `wrangler tail` for Cloudflare or `docker logs` for self-hosted deployments.
-   Only `AUTH_CONFIG_MISSING` exposes detailed error messages to clients; other codes return sanitized responses for security.

## Frequently Asked Questions

### How do I identify which error code Open-SEO returned?

Import `getErrorCode` from `@/client/lib/error-messages.ts` and pass the caught error object to it. This function extracts the machine-readable code (e.g., `VALIDATION_ERROR`) from the server response, allowing you to implement conditional logic or display specific UI messages based on the failure type.

### Why am I seeing AUTH_CONFIG_MISSING errors?

This code indicates missing required environment variables such as `TEAM_DOMAIN`, `CLOUDFLARE_ACCESS_TOKEN`, or Better-Auth configuration keys. Unlike other Open-SEO errors, this code exposes detailed diagnostic messages to the client. Verify your environment files against the requirements listed in [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md) and ensure all variables are loaded before the server starts.

### How can I view detailed error logs for Open-SEO?

For Cloudflare Worker deployments, use the `wrangler tail` command to stream logs in real-time and search for entries containing `server.function error:`. For Docker or self-hosted instances, run `docker logs <container_name>` to view stdout output. The `errorHandlingMiddleware` automatically prints stack traces via `console.error` for every caught exception.

### What's the difference between VALIDATION_ERROR and INTERNAL_ERROR?

`VALIDATION_ERROR` indicates the request failed input validation checks (such as malformed domains or missing required fields) and typically originates in utility functions like [`src/server/lib/domainUtils.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/domainUtils.ts). `INTERNAL_ERROR` represents uncaught exceptions or bugs in business logic that escaped explicit error handling. Validation errors are not reported to PostHog telemetry to avoid dashboard noise, while internal errors are always captured if telemetry is enabled.