{"record":{"id":"c6202df2bd88eaff","repo":"paperclipai/paperclip","slug":"enter-a-cursor-api-key","errorCode":null,"errorMessage":"Enter a Cursor API key.","messagePattern":"Enter a Cursor API key\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ui/src/components/new-agent/NewAgentSetup.tsx","lineNumber":386,"sourceCode":"          : {}),\n      };\n    }\n    return config;\n  }\n  function preparedConfig(nextConnection = connection) {\n    if (multiProvider && (!model.trim() || !model.includes(\"/\")))\n      throw new Error(\"Choose or enter a model in provider/model format.\");\n    if (\n      adapterType === \"cursor_cloud\" &&\n      !/^https:\\/\\/github\\.com\\/[^/]+\\/[^/]+/.test(repository.trim())\n    )\n      throw new Error(\"Enter a GitHub repository URL.\");\n    if (\n      [\"cursor_cloud\", \"hermes_gateway\"].includes(adapterType) &&\n      !apiKey.trim() &&\n      !selectedBinding\n    )\n      throw new Error(\n        adapterType === \"cursor_cloud\"\n          ? \"Enter a Cursor API key.\"\n          : `Enter ${envKey} or select an organization secret.`,\n      );\n    if (adapterType === \"hermes_gateway\") {\n      try {\n        const url = new URL(gatewayUrl.trim());\n        if (![\"https:\", \"http:\"].includes(url.protocol)) throw new Error();\n      } catch {\n        throw new Error(\"Enter the Hermes API base URL.\");\n      }\n    }\n    if (usingKimiApi && !kimiModel.trim())\n      throw new Error(\"Enter the Kimi API model name.\");\n    return buildConfig(nextConnection);\n  }\n  function pendingCredentials(nextConnection = connection) {\n    return {","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/ui/src/components/new-agent/NewAgentSetup.tsx#L368-L404","documentation":"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.","triggerScenarios":"Submitting setup with adapterType \"cursor_cloud\", the API key field empty, and no org secret selected from selectedBinding.","commonSituations":"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.","solutions":["Paste a valid Cursor API key into the API key field.","Or select an existing organization secret binding via selectedBinding instead of a raw key.","If no org secret exists, create one for the Cursor key, then select it.","Re-check the field after switching adapter types — the key may have been cleared."],"exampleFix":"// before: relying on an unset default\napiKey: \"\",\nselectedBinding: null\n\n// after: bind the org secret (or paste the key)\nselectedBinding: { id: \"org-secret-cursor\", label: \"CURSOR_API_KEY\" }","handlingStrategy":"validation","validationCode":"const keyOk =\n  !(\"cursor_cloud\" === adapterType) ||\n  apiKey.trim().length > 0 ||\n  selectedBinding != null;\nif (!keyOk) showError(\"Enter a Cursor API key.\");","typeGuard":"const hasCredential =\n  (apiKey: string, binding: { id: string } | null): boolean =>\n    apiKey.trim().length > 0 || binding != null;","tryCatchPattern":"try {\n  const cfg = preparedConfig();\n  submit(cfg);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"API key\")) {\n    setKeyFieldError(e.message);\n  } else throw e;\n}","preventionTips":["Provide either a raw API key or an org secret binding — at least one.","Re-verify credentials after switching adapter types mid-flow.","Provision org secrets before rolling out adapter setup to users.","Trim pasted keys to avoid whitespace-only values."],"tags":["validation","form","api-key","cursor-cloud"],"backgroundTag":"missing-api-key","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}