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
- 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).
- 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.
- Verify the variable name is exactly MORPH_API_KEY (case-sensitive) and that you have a valid key from morphllm.com.
- 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.
- 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
- Add MORPH_API_KEY to .env locally (copy from .env.example) and to hosting secrets for every environment (preview, production, CI).
- Restart the dev server after changing .env — Next.js does not reload env changes on the fly.
- Check env var spelling/casing exactly: MORPH_API_KEY.
- Validate required env vars at application startup so misconfiguration surfaces at boot, not mid-request.
- Rotate keys safely and verify the new key works with a curl against https://api.morphllm.com/v1/chat/completions before deploying.
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
- Firecrawl API key not configured
- FIRECRAWL_API_KEY environment variable is not set
- No available method to write files to sandbox
- Unknown sandbox provider: ${selectedProvider}. Supported pro
AI-assisted analysis of firecrawl/open-lovable@69bd93bae7 (2026-08-28).
Data as JSON: /api/errors/cb451d94682b3171.
Report an issue: GitHub.