bytedance/deer-flow · critical

result.message

Error message

result.message

What it means

This error is thrown by the Next.js workspace server layout when the Gateway's bootstrap/config endpoint returns a 'config_error' status. The layout calls a config-loading routine whose result is a discriminated union; the 'config_error' branch re-throws the backend-supplied message as a render-time exception, which Next.js converts into a 500 error page (or the dev overlay). It means the Gateway booted far enough to answer, but the server-side config payload it returned was invalid.

Source

Thrown at frontend/src/app/workspace/layout.tsx:50

      break;
    case "needs_setup":
      redirect("/setup");
    case "system_setup_required":
      redirect("/setup");
    case "unauthenticated":
      redirect("/login");
    case "gateway_unavailable":
      // GatewayOfflineFallback supplies the AuthProvider; WorkspaceContent
      // already mounts the banner inside its sidebar layout, so renderBanner
      // stays false here to avoid double-mounting.
      content = (
        <GatewayOfflineFallback>
          <WorkspaceContent gatewayUnavailable>{children}</WorkspaceContent>
        </GatewayOfflineFallback>
      );
      break;
    case "config_error":
      throw new Error(result.message);
    default:
      assertNever(result);
  }

  return <I18nProvider initialLocale={locale}>{content}</I18nProvider>;
}

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Run `make doctor` (repo root) — it validates config.yaml and reports the exact offending key/section.
  2. Open config.yaml and compare against config.example.yaml; fix YAML syntax (tabs, quotes, indentation) and invalid enum values.
  3. If unsure, back up config.yaml, re-copy from config.example.yaml, and re-apply your edits incrementally, restarting the Gateway after each change.
  4. Check the Gateway logs for the detailed config-load traceback — the layout only re-throws the summary message.

Example fix

# before (broken config.yaml)
models:
  basic: { provider: openrouter }
  basic_model: [ ]   # wrong shape

# after
models:
  basic:
    provider: openrouter
    basic_model: deepseek/deepseek-chat
Defensive patterns

Strategy: validation

Validate before calling

// Before rendering the workspace, validate config via the Gateway:
const res = await fetch(`${backend}/api/config/validate`, { cache: 'no-store' });
if (!res.ok) {
  // route to a settings/error page instead of letting the layout throw
  redirect('/workspace/setup?reason=config_error');
}

Type guard

function isConfigError(
  result: BootstrapResult,
): result is { status: 'config_error'; message: string } {
  return result.status === 'config_error' && typeof result.message === 'string';
}

Try / catch

// In an error boundary one level above the layout:
try {
  renderWorkspace();
} catch (e) {
  if (e instanceof Error && /config/i.test(e.message)) showConfigHelp(e.message);
  else throw e;
}

Prevention

When it happens

Trigger: GET of the workspace bootstrap endpoint returns {status:'config_error', message:...} — typically because config.yaml at the repo root is malformed YAML, references an unknown key/enum, or points at a missing file. Visiting /workspace/* while the Gateway runs with a broken config.yaml produces this throw during server render of frontend/src/app/workspace/layout.tsx.

Common situations: Editing config.yaml by hand and leaving a syntax error; copying config.example.yaml incompletely; a schema change after upgrading DeerFlow making old keys invalid; a stray environment variable overriding a config value with a bad type.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/59424c0d63a41680. Report an issue: GitHub.