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
- Discard the stale tool call and re-issue it within the current turn's correlation context.
- Ensure the client reads the current runId/sessionId/turnId from the admitted turn before sending tool responses.
- 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
- Never cache tool-call handles across turn boundaries.
- Subscribe to turn-rotation events and cancel in-flight calls on rotation.
- Include runId/sessionId/turnId checks client-side before submitting results.
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
- SSH env-lab fixture state exists, but the process is not run
- Worktree seed manifest source path does not match the regist
- Worktree seed manifest source instance does not match the re
- Worktree seed manifest target instance does not match the re
- Installing or updating Paperclip requires Node.js ${MINIMUM_
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/1311f8bf104b58e5.
Report an issue: GitHub.