paperclipai/paperclip · error · PaperclipRunnerProviderProfileError

paperclip_runner_claude_managed_spend_cap_invalid

paperclip_runner_claude_managed_spend_cap_invalid

Error message

The Claude Managed profile requires a positive session spend ceiling.

What it means

Every claude_managed run carries a session spend ceiling (maxSessionListCostUsd), taken from the adapter profile override or the stored profile's defaultMaxListCostCents/100. If the resolved value is missing, non-finite, or <= 0, the run is refused. This enforces Paperclip's budget hard-stop invariant on Managed Agents sessions.

Source

Thrown at server/src/services/native-runtime/provider-profile.ts:518

      );
    }
    const model = profile.model ?? optionalString(stored.defaultModel);
    const maxSessionListCostUsd = profile.maxSessionListCostUsd
      ?? stored.defaultMaxListCostCents / 100;
    if (!model) {
      throw new PaperclipRunnerProviderProfileError(
        "paperclip_runner_claude_managed_model_invalid",
        "The Claude Managed profile requires a model.",
      );
    }
    if (model !== CLAUDE_MANAGED_QUALIFIED_MODEL) {
      throw new PaperclipRunnerProviderProfileError(
        "paperclip_runner_claude_managed_model_unqualified",
        `The Claude Managed profile requires exact model ${CLAUDE_MANAGED_QUALIFIED_MODEL}.`,
      );
    }
    if (!Number.isFinite(maxSessionListCostUsd) || maxSessionListCostUsd <= 0) {
      throw new PaperclipRunnerProviderProfileError(
        "paperclip_runner_claude_managed_spend_cap_invalid",
        "The Claude Managed profile requires a positive session spend ceiling.",
      );
    }
    return {
      provider: "claude_managed",
      model,
      managedProfile: {
        profileId: stored.id,
        anthropicAgentId: stored.anthropicAgentId,
        agentVersion: stored.agentVersion,
        environmentId: stored.environmentId,
        betaVersion: CLAUDE_MANAGED_BETA_VERSION,
      },
      maxSessionListCostUsd,
    };
  }
  if (profile.provider === "aws_agentcore") {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Set maxSessionListCostUsd in the adapter profile config to a positive finite number (e.g. 25).
  2. Set defaultMaxListCostCents on the stored managed profile to a positive integer (e.g. 2500 for $25).
  3. Re-run managed agent setup so the spend ceiling defaults are written correctly.
  4. Fix the DB row if defaultMaxListCostCents is null/0/text after a migration or restore.

Example fix

// before
providerProfile: { provider: "claude_managed", managedProfileId: "acme-managed", model: "claude-sonnet-5", maxSessionListCostUsd: 0 }
// after
providerProfile: { provider: "claude_managed", managedProfileId: "acme-managed", model: "claude-sonnet-5", maxSessionListCostUsd: 25 }
Defensive patterns

Strategy: validation

Validate before calling

const cap = profile.maxSessionListCostUsd ?? (storedProfile.defaultMaxListCostCents ?? 0) / 100;
if (!(typeof cap === "number" && Number.isFinite(cap) && cap > 0)) {
  throw new Error("Configure a positive maxSessionListCostUsd (or defaultMaxListCostCents > 0) before running claude_managed");
}

Type guard

const hasPositiveCap = (v: unknown): v is number =>
  typeof v === "number" && Number.isFinite(v) && v > 0;

Try / catch

try {
  await executeRun(run);
} catch (e) {
  if (e instanceof PaperclipRunnerProviderProfileError && e.code === "paperclip_runner_claude_managed_spend_cap_invalid") {
    await managedProfileService.update(profileId, { defaultMaxListCostCents: 2500 }); // $25
    return executeRun(run);
  }
  throw e;
}

Prevention

When it happens

Trigger: provider=claude_managed run where profile.maxSessionListCostUsd is absent/0/negative and stored.defaultMaxListCostCents is 0, negative, null, or non-numeric (making the division NaN).

Common situations: A profile seeded with defaultMaxListCostCents left at 0; a run config that explicitly sets maxSessionListCostUsd: 0 intending 'no limit'; a corrupted/migrated profile row where the cents column lost its numeric type.

Related errors


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