{"record":{"id":"1181743c3b07ef49","repo":"paperclipai/paperclip","slug":"paperclipai-connect-is-interactive-for-scripts","errorCode":null,"errorMessage":"`paperclipai connect` is interactive. For scripts, pass --api-base/--api-key or use context set/token commands.","messagePattern":"`paperclipai connect` is interactive\\. For scripts, pass --api-base/--api-key or use context set/token commands\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"cli/src/commands/client/connect.ts","lineNumber":58,"sourceCode":"      .command(\"connect\")\n      .description(\"Interactively connect the CLI as a board operator or agent\")\n      .option(\"--persona <persona>\", \"Persona to configure: board or agent\")\n      .option(\"--api-key-env-var-name <name>\", \"Env var name to store in the profile\", \"PAPERCLIP_API_KEY\")\n      .option(\"--token-name <name>\", \"Token label to create\")\n      .action(async (opts: ConnectOptions) => {\n        try {\n          const result = await connectWizard(opts);\n          printOutput(result, { json: opts.json });\n        } catch (err) {\n          handleCommandError(err);\n        }\n      }),\n  );\n}\n\nasync function connectWizard(opts: ConnectOptions) {\n  if (!process.stdin.isTTY || !process.stdout.isTTY) {\n    throw new Error(\"`paperclipai connect` is interactive. For scripts, pass --api-base/--api-key or use context set/token commands.\");\n  }\n\n  p.intro(pc.bgCyan(pc.black(\" paperclipai connect \")));\n\n  const context = readContext(opts.context);\n  const resolvedProfile = resolveProfile(context, opts.profile);\n  const initialApiBase = resolveApiBase(opts, resolvedProfile.profile);\n  const apiBaseInput = await p.text({\n    message: \"Paperclip API base\",\n    initialValue: initialApiBase,\n    placeholder: \"http://localhost:3100\",\n  });\n  assertNotCancelled(apiBaseInput);\n  const apiBase = normalizeApiBase(String(apiBaseInput || initialApiBase));\n  console.log(pc.dim(`Checking ${apiBase}/api/health ...`));\n  await verifyHealth(apiBase);\n\n  const boardLogin = await loginBoardCli({","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/client/connect.ts#L40-L76","documentation":"Thrown by connectWizard() at the very start when either process.stdin or process.stdout is not a TTY. The `paperclipai connect` command is an interactive wizard (uses @clack/prompts) that requires both streams to be interactive. In non-interactive contexts (pipes, CI, cron, redirected I/O) the prompts cannot render, so it aborts immediately.","triggerScenarios":"Running `paperclipai connect` inside CI, Docker with no TTY, a shell script with piped stdin/stdout, a cron job, or any non-interactive subshell; piping output to a file or another command.","commonSituations":"Automated provisioning scripts that call `connect`; Docker containers run without `-it`; SSH non-interactive commands; build pipelines.","solutions":["Use non-interactive alternatives: `paperclipai context set` and `paperclipai token` with --api-base/--api-key flags.","Set PAPERCLIP_API_BASE and PAPERCLIP_API_KEY environment variables directly.","Allocate a TTY for interactive runs (e.g. `docker run -it`, `ssh -t`)."],"exampleFix":"# before (non-interactive)\npaperclipai connect < /dev/null\n# after (non-interactive setup)\nexport PAPERCLIP_API_BASE=http://localhost:3100\nexport PAPERCLIP_API_KEY=$KEY\npaperclipai context set --profile default --api-base \"$PAPERCLIP_API_BASE\"","handlingStrategy":"validation","validationCode":"// Detect non-interactive context before calling connect, and use the non-interactive path.\nfunction isInteractive(): boolean {\n  return !!process.stdin.isTTY && !!process.stdout.isTTY;\n}\nif (!isInteractive()) {\n  throw new Error(\"Non-interactive shell: use 'paperclipai context set' + env vars instead of 'connect'.\");\n}","typeGuard":"function isTtyContext(): boolean {\n  return process.stdin.isTTY === true && process.stdout.isTTY === true;\n}","tryCatchPattern":null,"preventionTips":["In CI/Docker, set PAPERCLIP_API_BASE and PAPERCLIP_API_KEY directly instead of calling connect.","Use `paperclipai context set` for scripted profile configuration.","Allocate a TTY (docker run -it, ssh -t) only for interactive onboarding."],"tags":["cli","connect","interactive","tty","non-interactive"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}