{"record":{"id":"8057f53809f3e388","repo":"paperclipai/paperclip","slug":"paperclip-runner-aws-agentcore-spend-cap-invalid","errorCode":"paperclip_runner_aws_agentcore_spend_cap_invalid","errorMessage":"The AWS AgentCore profile requires a positive estimated session spend ceiling.","messagePattern":"The AWS AgentCore profile requires a positive estimated session spend ceiling\\.","errorType":"error_code","errorClass":"PaperclipRunnerProviderProfileError","httpStatus":null,"severity":"error","filePath":"server/src/services/native-runtime/provider-profile.ts","lineNumber":574,"sourceCode":"          `The qualified AWS AgentCore profile is missing ${key}.`,\n        );\n      }\n      return value;\n    };\n    if (remote.eventExpiryDays !== 90) {\n      throw new PaperclipRunnerProviderProfileError(\n        \"paperclip_runner_aws_agentcore_retention_unqualified\",\n        \"The qualified AWS AgentCore profile must retain Memory events for exactly 90 days.\",\n      );\n    }\n    const maxEstimatedSessionCostUsd = profile.maxEstimatedSessionCostUsd\n      ?? positiveNumberOrNull(\n        remote.defaultMaxEstimatedSessionCostUsd,\n        \"paperclip_runner_aws_agentcore_spend_cap_invalid\",\n        \"The AWS AgentCore profile requires a positive estimated session spend ceiling.\",\n      );\n    if (maxEstimatedSessionCostUsd === null) {\n      throw new PaperclipRunnerProviderProfileError(\n        \"paperclip_runner_aws_agentcore_spend_cap_invalid\",\n        \"The AWS AgentCore profile requires a positive estimated session spend ceiling.\",\n      );\n    }\n    const model = profile.model ?? required(\"defaultModel\");\n    if (model !== AGENTCORE_QUALIFIED_MODEL) {\n      throw new PaperclipRunnerProviderProfileError(\n        \"paperclip_runner_aws_agentcore_model_unqualified\",\n        `The AWS AgentCore profile requires exact model ${AGENTCORE_QUALIFIED_MODEL}.`,\n      );\n    }\n    return {\n      provider: \"aws_agentcore\",\n      model,\n      agentCoreProfile: {\n        profileId: stored.id,\n        region: required(\"region\"),\n        accountId: required(\"accountId\"),","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/native-runtime/provider-profile.ts#L556-L592","documentation":"AWS AgentCore runs require a positive estimated session cost ceiling (maxEstimatedSessionCostUsd), resolved from the adapter profile override or the stored configuration's defaultMaxEstimatedSessionCostUsd via positiveNumberOrNull. positiveNumberOrNull itself throws this same error when the stored default is present but not a positive finite number; a second throw fires when both sources are absent (null). This enforces the budget hard-stop invariant for AgentCore sessions.","triggerScenarios":"provider=aws_agentcore run where profile.maxEstimatedSessionCostUsd is unset and stored.configuration.defaultMaxEstimatedSessionCostUsd is either absent (first throw at line 568) or set to 0, negative, or a non-numeric value (throw from positiveNumberOrNull at line 562-565).","commonSituations":"A qualified profile stored without a spend default; a run config setting maxEstimatedSessionCostUsd: 0 to mean 'unlimited'; a configuration edit that wrote the ceiling as a string like \"20.00\".","solutions":["Set maxEstimatedSessionCostUsd in the adapter profile config to a positive finite number (e.g. 20).","Set stored.configuration.defaultMaxEstimatedSessionCostUsd to a positive number so runs inherit a default.","Fix the stored value's type — it must be a JSON number, not a string, and greater than 0.","Re-run the AgentCore qualification flow so the spend default is written as part of qualification."],"exampleFix":"// before (stored configuration)\n{ \"defaultMaxEstimatedSessionCostUsd\": 0, ... }\n// after\n{ \"defaultMaxEstimatedSessionCostUsd\": 20, ... }","handlingStrategy":"validation","validationCode":"const cap = profile.maxEstimatedSessionCostUsd ?? storedProfile.configuration?.defaultMaxEstimatedSessionCostUsd;\nif (!(typeof cap === \"number\" && Number.isFinite(cap) && cap > 0)) {\n  throw new Error(\"Set a positive maxEstimatedSessionCostUsd (or defaultMaxEstimatedSessionCostUsd) before running aws_agentcore\");\n}","typeGuard":"const isPositiveUsd = (v: unknown): v is number =>\n  typeof v === \"number\" && Number.isFinite(v) && v > 0;","tryCatchPattern":"try {\n  await executeRun(run);\n} catch (e) {\n  if (e instanceof PaperclipRunnerProviderProfileError && e.code === \"paperclip_runner_aws_agentcore_spend_cap_invalid\") {\n    await agentCoreProfileService.updateConfiguration(profileId, { defaultMaxEstimatedSessionCostUsd: 20 });\n    return executeRun(run);\n  }\n  throw e;\n}","preventionTips":["Store defaultMaxEstimatedSessionCostUsd during qualification so every profile has a default","Use a positive number, not 0, to express any ceiling — there is no 'unlimited' value","Keep it a JSON number; strings like \"20.00\" fail positiveNumberOrNull","Mirror the Claude Managed spend-cap habit: always configure a cap per adapter profile"],"tags":["configuration","budget","spend-cap","aws-agentcore"],"backgroundTag":"invalid-spend-cap","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-02T18:44:00.616Z","contentChangedAt":"2026-09-02T18:44:00.616Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}