paperclipai/paperclip · error

eval-session acpxAgent requires provider acpx

Error message

eval-session acpxAgent requires provider acpx

What it means

acpxAgent is only meaningful when provider is 'acpx'. If any other provider (codex, opencode, claude_managed, aws_agentcore) is selected and acpxAgent is defined, parseEvalSessionRequest rejects the request rather than silently ignoring the field. This keeps the fail-closed contract from mixing provider-specific options.

Source

Thrown at packages/paperclip-runner/src/cli/eval-session-contract.ts:249

  const provider = providerValue;
  const driver = expectedEvalSessionDriver(provider);
  if (input.driver !== undefined && input.driver !== driver) {
    throw new Error("eval-session provider/driver mismatch");
  }
  // The original Evalbook v1 producer serialized absent provider-specific
  // options as JSON null. Preserve compatibility with those immutable request
  // artifacts while continuing to reject non-null values for the wrong lane.
  const acpxAgent = input.acpxAgent === null ? undefined : input.acpxAgent;
  if (acpxAgent === "pi") throw new Error("The Pi ACPX profile is not available");
  if (
    acpxAgent !== undefined &&
    acpxAgent !== "codex" &&
    acpxAgent !== "claude"
  ) {
    throw new Error("eval-session acpxAgent must be codex or claude");
  }
  if (provider !== "acpx" && acpxAgent !== undefined) {
    throw new Error("eval-session acpxAgent requires provider acpx");
  }
  const managedProfileInput = input.managedProfile === null
    ? undefined
    : input.managedProfile;
  const agentCoreProfileInput = input.agentCoreProfile === null
    ? undefined
    : input.agentCoreProfile;
  const managedProfile = provider === "claude_managed"
    ? parseManagedProfile(managedProfileInput)
    : undefined;
  const agentCoreProfile = provider === "aws_agentcore"
    ? parseAgentCoreProfile(agentCoreProfileInput)
    : undefined;
  if (provider !== "claude_managed" && managedProfileInput !== undefined) {
    throw new Error("eval-session managedProfile requires provider claude_managed");
  }
  if (provider !== "aws_agentcore" && agentCoreProfileInput !== undefined) {
    throw new Error("eval-session agentCoreProfile requires provider aws_agentcore");

View on GitHub (pinned to 01ad858492)

Solutions

  1. Remove the acpxAgent field when provider is not 'acpx'.
  2. Set provider to 'acpx' if the ACPX agent is actually intended.
  3. Make the request builder conditionally include acpxAgent only for provider 'acpx'.
  4. Strip provider-irrelevant fields from the config before constructing the request.

Example fix

// before
const request = { schema, provider: "codex", acpxAgent: "codex", ... };
// after
const request = { schema, provider: "codex", ... };
// or, if ACPX was intended:
const request = { schema, provider: "acpx", acpxAgent: "codex", ... };
Defensive patterns

Strategy: validation

Validate before calling

function assertAcpxAgentProviderPair(request: { provider?: string; acpxAgent?: string }): void {
  const provider = request.provider ?? "codex";
  if (provider !== "acpx" && request.acpxAgent !== undefined) {
    throw new Error(`acpxAgent set but provider is '${provider}'; acpxAgent requires provider 'acpx'`);
  }
}

Type guard

function acpxAgentAllowed(r: { provider?: string; acpxAgent?: unknown }): boolean {
  return r.acpxAgent === undefined || (r.provider ?? "codex") === "acpx";
}

Try / catch

try {
  const parsed = parseEvalSessionRequest(raw);
} catch (err) {
  if (err instanceof Error && err.message === "eval-session acpxAgent requires provider acpx") {
    console.error(`Remove acpxAgent or set provider to 'acpx' (got provider='${raw.provider ?? "codex"}').`);
  } else throw err;
}

Prevention

When it happens

Trigger: A request like {provider:'codex', acpxAgent:'codex'} or {provider:'claude_managed', acpxAgent:'claude'} — the agent field leaks in from an ACPX-shaped template while provider was changed to something else.

Common situations: Reusing one request-builder for all providers and always setting acpxAgent; switching provider in a config file but leaving the acpx block in place; merged/templated config that carries stale ACPX keys.

Related errors


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