paperclipai/paperclip · error

Capability live messages cannot be empty

Error message

Capability live messages cannot be empty

What it means

CapabilityLiveSession.sendMessage rejects empty messages. The incoming string is trimmed and if the result has length 0 the method throws before any transport work is done, because an empty user turn would create a meaningless Codex turn.

Source

Thrown at packages/paperclip-runner/src/live/live-session.ts:1461

    ) {
      throw new Error("capability_live_attempt_active_turn");
    }
    attempt.status = status;
    attempt.finishedAt = this.#now().toISOString();
    attempt.failureCode = status === "failed"
      ? requireNonEmpty(failureCode ?? "attempt_failed", "attempt_failure_code")
      : null;
    await this.#persist();
    return this.snapshot();
  }

  async sendMessage(
    message: string,
    /** Launch-only diagnostics may opt out; qualification campaigns must not. */
    options: { allowMissingUsage?: boolean } = {},
  ): Promise<CapabilityLiveTurnResult> {
    const value = message.trim();
    if (value.length === 0) throw new Error("Capability live messages cannot be empty");
    if (this.#status === "suspended" || this.#transport === null) {
      await this.#connect(true);
    }
    if (this.#transport === null || this.#status === "closed" || this.#status === "failed") {
      throw new Error("Capability live session is not connected");
    }
    if (
      this.#activeTurnId !== null ||
      this.#turnWaiter !== null ||
      this.#pendingTurnAdmission !== null
    ) {
      throw new Error("Capability live session already has an active turn");
    }
    let settleAdmission!: () => void;
    const admission: PendingTurnAdmission = {
      transport: this.#transport,
      cancellation: null,
      settled: new Promise<void>((resolveSettled) => {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Provide a non-empty message string
  2. Trim/validate user input before calling sendMessage and skip the call when empty
  3. Check whether an upstream field defaults to '' and supply a real prompt

Example fix

// before
await session.sendMessage(userInput); // '' or whitespace throws
// after
const trimmed = (userInput ?? '').trim();
if (trimmed.length > 0) await session.sendMessage(trimmed);
Defensive patterns

Strategy: validation

Validate before calling

const trimmed = (message ?? '').trim();
if (trimmed.length === 0) throw new Error('refusing to send empty live message');

Type guard

function isSendableMessage(m: unknown): m is string {
  return typeof m === 'string' && m.trim().length > 0;
}

Try / catch

try {
  await session.sendMessage(message);
} catch (e) {
  if ((e as Error).message === 'Capability live messages cannot be empty') {
    // skip turn; fix input source
  } else throw e;
}

Prevention

When it happens

Trigger: Calling sendMessage('') or sendMessage(' \n') — any string that is empty after trimming.

Common situations: UI sending an empty input box value; a pipeline forwarding an optional message field that is undefined coerced to empty string; templated prompts that resolve to whitespace only.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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