{"record":{"id":"9e18ae6fd8234b47","repo":"paperclipai/paperclip","slug":"custom-createos-api-endpoints-require-an-explicit","errorCode":null,"errorMessage":"Custom CreateOS API endpoints require an explicit environment API key; the host fallback is only available for https://api.sb.createos.sh.","messagePattern":"Custom CreateOS API endpoints require an explicit environment API key; the host fallback is only available for https://api\\.sb\\.createos\\.sh\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/sandbox-providers/createos/src/config.ts","lineNumber":54,"sourceCode":"    throw new Error(\"timeoutMs must be an integer between 1 and 86400000.\");\n  }\n  if (raw.reuseLease != null && typeof raw.reuseLease !== \"boolean\") {\n    throw new Error(\"reuseLease must be a boolean.\");\n  }\n  return {\n    apiUrl: url.origin,\n    apiKey: text(\"apiKey\"),\n    shape,\n    rootfs: text(\"rootfs\"),\n    region: text(\"region\"),\n    timeoutMs,\n    reuseLease: raw.reuseLease === true,\n  };\n}\n\nexport function resolveApiKey(config: CreateosConfig): string {\n  if (!config.apiKey && config.apiUrl !== \"https://api.sb.createos.sh\") {\n    throw new Error(\"Custom CreateOS API endpoints require an explicit environment API key; the host fallback is only available for https://api.sb.createos.sh.\");\n  }\n  const key = config.apiKey ?? process.env.CREATEOS_API_KEY?.trim();\n  if (!key || /[\\r\\n\\0]/.test(key)) {\n    throw new Error(\"CreateOS requires an API key in the environment config or CREATEOS_API_KEY.\");\n  }\n  return key;\n}\n","sourceCodeStart":36,"sourceCodeEnd":62,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/plugins/sandbox-providers/createos/src/config.ts#L36-L62","documentation":"resolveApiKey enforces that a custom (non-default) CreateOS API endpoint must carry an explicit apiKey in the environment config. Only the well-known host https://api.sb.createos.sh may omit it and fall back to the CREATEOS_API_KEY environment variable. This stops the shared/global credential from silently being sent to arbitrary third-party hosts.","triggerScenarios":"Calling resolveApiKey (directly or via the plugin constructor or its account method) with a config whose apiUrl is any origin other than https://api.sb.createos.sh while config.apiKey is empty/missing.","commonSituations":"Pointing the plugin at a self-hosted or regional CreateOS endpoint (or a loopback http://localhost dev server) and relying on the CREATEOS_API_KEY env var, which the fallback policy only permits for the default host.","solutions":["Add an explicit apiKey to the CreateOS environment config for the custom endpoint.","Or switch apiUrl back to https://api.sb.createos.sh so the CREATEOS_API_KEY env fallback is allowed.","If this endpoint is actually the official API, fix a typo/proxy prefix in apiUrl so it matches the default host exactly."],"exampleFix":"// before\n{ \"apiUrl\": \"https://eu.createos.example/v1\" } // relies on CREATEOS_API_KEY\n// after\n{ \"apiUrl\": \"https://eu.createos.example/v1\", \"apiKey\": \"ck_live_...\" }","handlingStrategy":"validation","validationCode":"if (cfg.apiUrl !== 'https://api.sb.createos.sh' && !cfg.apiKey) {\n  throw new Error('Custom CreateOS endpoints require an explicit apiKey in the environment config');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair every custom apiUrl with an explicit apiKey at config-authoring time","Rely on CREATEOS_API_KEY fallback only for the default api.sb.createos.sh host","Keep a config checklist item: custom host => dedicated key"],"tags":["config","api-key","security","credentials"],"backgroundTag":"missing-credentials","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-22T10:30:35.592Z"}