firecrawl/open-lovable · error · Error

MORPH_API_KEY is not set

Error message

MORPH_API_KEY is not set

What it means

This error is thrown at the top of morphChatCompletionsCreate in lib/morph-fast-apply.ts:43 as a fail-fast guard: the module talks directly to Morph's OpenAI-compatible endpoint (https://api.morphllm.com/v1/chat/completions) and refuses to make the network call when process.env.MORPH_API_KEY is falsy. It is a deliberate configuration check, not a network failure — the request is never sent, so the caller always gets a local, deterministic error instead of a confusing 401 from Morph.

Source

Thrown at lib/morph-fast-apply.ts:43

    'package-lock.json',
    'tsconfig.json',
    'postcss.config.js'
  ]);

  const fileName = normalizedPath.split('/').pop() || '';
  if (!normalizedPath.startsWith('src/') &&
      !normalizedPath.startsWith('public/') &&
      normalizedPath !== 'index.html' &&
      !configFiles.has(fileName)) {
    normalizedPath = 'src/' + normalizedPath;
  }

  const fullPath = `/home/user/app/${normalizedPath}`;
  return { normalizedPath, fullPath };
}

async function morphChatCompletionsCreate(payload: any) {
  if (!process.env.MORPH_API_KEY) throw new Error('MORPH_API_KEY is not set');
  const res = await fetch('https://api.morphllm.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.MORPH_API_KEY}`
    },
    body: JSON.stringify(payload)
  });
  if (!res.ok) {
    const text = await res.text();
    throw new Error(`Morph API error ${res.status}: ${text}`);
  }
  return res.json();
}

// Parse <edit> blocks from LLM output
export function parseMorphEdits(text: string): MorphEditBlock[] {
  const edits: MorphEditBlock[] = [];

View on GitHub (pinned to 69bd93bae7)

Solutions

  1. Set MORPH_API_KEY in your .env file locally: echo 'MORPH_API_KEY=morph-...' >> .env, then restart the dev server (Next.js does not hot-reload new env vars).
  2. Add MORPH_API_KEY to the production/hosting environment secrets (Vercel project settings, Docker env, CI secrets) and redeploy so the running process picks it up.
  3. Verify the variable name is exactly MORPH_API_KEY (case-sensitive) and that you have a valid key from morphllm.com.
  4. Add a startup validation or a clear user-facing response mapping so this error tells the operator to configure the key rather than surfacing a raw 500.
  5. Optionally lazy-check at module load (or a config module) so misconfiguration is caught at boot instead of mid-request.

Example fix

// before
async function morphChatCompletionsCreate(payload: any) {
  if (!process.env.MORPH_API_KEY) throw new Error('MORPH_API_KEY is not set');
  const res = await fetch('https://api.morphllm.com/v1/chat/completions', {
// after
async function morphChatCompletionsCreate(payload: any) {
  if (!process.env.MORPH_API_KEY) {
    throw new Error('MORPH_API_KEY is not set. Add it to .env or your hosting env secrets and restart.');
  }
  const res = await fetch('https://api.morphllm.com/v1/chat/completions', {
Defensive patterns

Strategy: validation

Validate before calling

function requireMorphApiKey(): string {
  const key = process.env.MORPH_API_KEY;
  if (!key) throw new Error('MORPH_API_KEY is not set — add it to .env or your host env secrets and restart');
  return key;
}
// call before any Morph operation
const apiKey = requireMorphApiKey();

Type guard

function hasMorphApiKey(env: NodeJS.ProcessEnv = process.env): env is NodeJS.ProcessEnv & { MORPH_API_KEY: string } {
  return typeof env.MORPH_API_KEY === 'string' && env.MORPH_API_KEY.length > 0;
}

Try / catch

try {
  const result = await applyWithMorph(editBlock);
} catch (e) {
  if ((e as Error).message.includes('MORPH_API_KEY is not set')) {
    return { success: false, error: 'Morph is not configured: set MORPH_API_KEY in your environment' };
  }
  throw e;
}

Prevention

When it happens

Trigger: Any apply/edit flow that reaches morphChatCompletionsCreate (called from the resp path of morph-fast-apply.ts) while MORPH_API_KEY is absent from the runtime environment: local dev without .env, deployment (Vercel/Docker) where the secret was never added, a typo like MORPH_MORPH_API_KEY or MOPRH_API_KEY, or code running in a context (edge runtime, test) that does not load the .env file.

Common situations: Fresh clone where .env.example wasn't copied to .env; adding the key locally but forgetting to add it to production env vars; CI/test environment lacking the secret; serverless deploy where env vars weren't redeployed after being set; wrong variable name casing.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of firecrawl/open-lovable@69bd93bae7 (2026-08-28). Data as JSON: /api/errors/cb451d94682b3171. Report an issue: GitHub.