paperclipai/paperclip · warning · Error
`paperclipai connect` is interactive. For scripts, pass --ap
Error message
`paperclipai connect` is interactive. For scripts, pass --api-base/--api-key or use context set/token commands.
What it means
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.
Source
Thrown at cli/src/commands/client/connect.ts:58
.command("connect")
.description("Interactively connect the CLI as a board operator or agent")
.option("--persona <persona>", "Persona to configure: board or agent")
.option("--api-key-env-var-name <name>", "Env var name to store in the profile", "PAPERCLIP_API_KEY")
.option("--token-name <name>", "Token label to create")
.action(async (opts: ConnectOptions) => {
try {
const result = await connectWizard(opts);
printOutput(result, { json: opts.json });
} catch (err) {
handleCommandError(err);
}
}),
);
}
async function connectWizard(opts: ConnectOptions) {
if (!process.stdin.isTTY || !process.stdout.isTTY) {
throw new Error("`paperclipai connect` is interactive. For scripts, pass --api-base/--api-key or use context set/token commands.");
}
p.intro(pc.bgCyan(pc.black(" paperclipai connect ")));
const context = readContext(opts.context);
const resolvedProfile = resolveProfile(context, opts.profile);
const initialApiBase = resolveApiBase(opts, resolvedProfile.profile);
const apiBaseInput = await p.text({
message: "Paperclip API base",
initialValue: initialApiBase,
placeholder: "http://localhost:3100",
});
assertNotCancelled(apiBaseInput);
const apiBase = normalizeApiBase(String(apiBaseInput || initialApiBase));
console.log(pc.dim(`Checking ${apiBase}/api/health ...`));
await verifyHealth(apiBase);
const boardLogin = await loginBoardCli({View on GitHub (pinned to 67001ec6eb)
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`).
Example fix
# before (non-interactive) paperclipai connect < /dev/null # after (non-interactive setup) export PAPERCLIP_API_BASE=http://localhost:3100 export PAPERCLIP_API_KEY=$KEY paperclipai context set --profile default --api-base "$PAPERCLIP_API_BASE"
Defensive patterns
Strategy: validation
Validate before calling
// Detect non-interactive context before calling connect, and use the non-interactive path.
function isInteractive(): boolean {
return !!process.stdin.isTTY && !!process.stdout.isTTY;
}
if (!isInteractive()) {
throw new Error("Non-interactive shell: use 'paperclipai context set' + env vars instead of 'connect'.");
} Type guard
function isTtyContext(): boolean {
return process.stdin.isTTY === true && process.stdout.isTTY === true;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Automated provisioning scripts that call `connect`; Docker containers run without `-it`; SSH non-interactive commands; build pipelines.
Related errors
- Applying a company import from a non-interactive terminal re
- Export output directory ${root} already contains files. Re-r
- Profile name is required
- This command requires --yes when not running in an interacti
- Applying a company import with --json requires --yes. Use --
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/1181743c3b07ef49.
Report an issue: GitHub.