paperclipai/paperclip · error

Enter a Cursor API key.

Error message

Enter a Cursor API key.

What it means

preparedConfig() requires an API key for the cursor_cloud and hermes_gateway adapter types: if apiKey is blank AND no organization secret binding (selectedBinding) is chosen, it throws. For cursor_cloud the message is specifically "Enter a Cursor API key." (for hermes_gateway it names the env key instead). The key may be entered directly or delegated to an org secret binding, but one of the two must be present.

Source

Thrown at ui/src/components/new-agent/NewAgentSetup.tsx:386

          : {}),
      };
    }
    return config;
  }
  function preparedConfig(nextConnection = connection) {
    if (multiProvider && (!model.trim() || !model.includes("/")))
      throw new Error("Choose or enter a model in provider/model format.");
    if (
      adapterType === "cursor_cloud" &&
      !/^https:\/\/github\.com\/[^/]+\/[^/]+/.test(repository.trim())
    )
      throw new Error("Enter a GitHub repository URL.");
    if (
      ["cursor_cloud", "hermes_gateway"].includes(adapterType) &&
      !apiKey.trim() &&
      !selectedBinding
    )
      throw new Error(
        adapterType === "cursor_cloud"
          ? "Enter a Cursor API key."
          : `Enter ${envKey} or select an organization secret.`,
      );
    if (adapterType === "hermes_gateway") {
      try {
        const url = new URL(gatewayUrl.trim());
        if (!["https:", "http:"].includes(url.protocol)) throw new Error();
      } catch {
        throw new Error("Enter the Hermes API base URL.");
      }
    }
    if (usingKimiApi && !kimiModel.trim())
      throw new Error("Enter the Kimi API model name.");
    return buildConfig(nextConnection);
  }
  function pendingCredentials(nextConnection = connection) {
    return {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Paste a valid Cursor API key into the API key field.
  2. Or select an existing organization secret binding via selectedBinding instead of a raw key.
  3. If no org secret exists, create one for the Cursor key, then select it.
  4. Re-check the field after switching adapter types — the key may have been cleared.

Example fix

// before: relying on an unset default
apiKey: "",
selectedBinding: null

// after: bind the org secret (or paste the key)
selectedBinding: { id: "org-secret-cursor", label: "CURSOR_API_KEY" }
Defensive patterns

Strategy: validation

Validate before calling

const keyOk =
  !("cursor_cloud" === adapterType) ||
  apiKey.trim().length > 0 ||
  selectedBinding != null;
if (!keyOk) showError("Enter a Cursor API key.");

Type guard

const hasCredential =
  (apiKey: string, binding: { id: string } | null): boolean =>
    apiKey.trim().length > 0 || binding != null;

Try / catch

try {
  const cfg = preparedConfig();
  submit(cfg);
} catch (e) {
  if (e instanceof Error && e.message.includes("API key")) {
    setKeyFieldError(e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: Submitting setup with adapterType "cursor_cloud", the API key field empty, and no org secret selected from selectedBinding.

Common situations: User expects the key to come from an environment/organization default but has not selected a binding; key was pasted with only whitespace; switching adapter types reset the field; first-time setup with no org secrets configured yet.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/c6202df2bd88eaff. Report an issue: GitHub.