paperclipai/paperclip · error · Error

--company-name cannot be empty.

Error message

--company-name cannot be empty.

What it means

When a semantic tool call arrives over PRP, the transport validates that the call's correlation (runId, normalizedSessionId, turnId) still matches the currently admitted turn identity on the active core. If the core instance changed, or any correlation field differs, the call is stale/belongs to another turn and is rejected with this error instead of being dispatched to the handler.

Source

Thrown at cli/src/commands/test-drive.ts:239

}

export function resolveTestDriveBootstrap(
  options: TestDriveOptions,
  env: NodeJS.ProcessEnv = process.env,
): ResolvedTestDriveBootstrap {
  if (options.apiKey !== undefined && options.apiKeyEnv !== undefined) {
    throw new Error("--api-key and --api-key-env are mutually exclusive.");
  }

  const harness = options.harness ?? "claude";
  const definition = HARNESS_DEFINITIONS[harness];
  if (!definition) {
    throw new Error(`Unsupported test-drive harness: ${String(harness)}.`);
  }

  const companyName = (options.companyName ?? "Test Company").trim();
  const agentName = (options.agentName ?? "CEO").trim();
  if (!companyName) throw new Error("--company-name cannot be empty.");
  if (!agentName) throw new Error("--agent-name cannot be empty.");

  const model = options.model;
  if (model !== undefined && (!model || model.trim() !== model)) {
    throw new Error("--model cannot be empty or have surrounding whitespace.");
  }
  if (
    harness === "opencode" &&
    (!model || !/^openrouter\/[^/\s]+(?:\/[^/\s]+)*$/.test(model))
  ) {
    throw new Error(
      "OpenCode test drives require --model openrouter/<model>, with no empty path segments.",
    );
  }

  const sourceEnvName = options.apiKeyEnv?.trim() || definition.credentialTarget;
  if (options.apiKeyEnv !== undefined && !/^[A-Za-z_][A-Za-z0-9_]*$/.test(sourceEnvName)) {
    throw new Error("--api-key-env must name a valid environment variable.");

View on GitHub (pinned to 01ad858492)

Solutions

  1. Discard the stale tool call and re-issue it within the current turn's correlation context.
  2. Ensure the client reads the current runId/sessionId/turnId from the admitted turn before sending tool responses.
  3. Avoid caching tool-call handles across turn boundaries; refetch per turn.

Example fix

// before
await respond(call, result); // stale correlation
// after
if (call.correlation.turnId === currentTurnId) await respond(call, result);
else await reissueToolCall(call, currentTurnId);
Defensive patterns

Strategy: type-guard

Validate before calling

function callMatchesTurn(call, identity) {
  return call.correlation.runId === identity.runId &&
    call.correlation.normalizedSessionId === identity.normalizedSessionId &&
    call.correlation.turnId === identity.turnId;
}
if (!callMatchesTurn(call, core.store.state.identity)) discardCall(call);

Type guard

function isCurrentTurnCall(call, core): call is ToolCall & { correlation: CurrentCorrelation } {
  const id = core.store.state.identity;
  return call.correlation.runId === id.runId &&
    call.correlation.normalizedSessionId === id.normalizedSessionId &&
    call.correlation.turnId === id.turnId;
}

Try / catch

try {
  await transport.respondToToolCall(call, result);
} catch (e) {
  if (e.message.includes("no longer belongs to an admitted turn")) {
    // drop stale call; refetch current turn identity and re-issue if still relevant
  }
}

Prevention

When it happens

Trigger: A queued or in-flight tool call executes after a new core/turn was admitted: `call.correlation.runId`, `normalizedSessionId`, or `turnId` no longer equals `core.store.state.identity` values, or `core !== this.#core`.

Common situations: A turn was cancelled or rotated while a tool call was still pending; replayed events from an old run delivered to a new turn; concurrent turns where a client keeps submitting tool results from a superseded turn.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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