{"record":{"id":"80b1c5335a2df8ae","repo":"paperclipai/paperclip","slug":"acpx-agent-profile-requires-exact-model-profi","errorCode":null,"errorMessage":"ACPX ${agent} profile requires exact model ${profile.qualificationModel}; received ${requestedModel}","messagePattern":"ACPX (.+?) profile requires exact model (.+?); received (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/acpx/qualified-profiles.ts","lineNumber":91,"sourceCode":"    agentServerVersion: \"1.6.2\",\n    agentRuntimePackage: \"@openai/codex\",\n    agentRuntimeVersion: \"0.153.4\",\n    commandDigest:\n      \"sha256:c4538599d1ab767db5dff50934f13bb5ba313a59d9c4a83e993fac4617ea63d3\",\n    qualificationModel: \"gpt-5.6-sol\",\n    reportedModelId: \"gpt-5.6-sol\",\n    permissionPolicy: \"interactive\",\n  },\n});\n\nexport function resolveQualifiedAcpxProfile(\n  agent: QualifiedAcpxAgent,\n  requestedModel: string,\n): QualifiedAcpxProfile {\n  const profile = QUALIFIED_ACPX_PROFILES[agent];\n  if (!requestedModel.trim()) throw new Error(\"ACPX model must not be empty\");\n  if (agent !== \"claude\" && requestedModel !== profile.qualificationModel) {\n    throw new Error(\n      `ACPX ${agent} profile requires exact model ${profile.qualificationModel}; received ${requestedModel}`,\n    );\n  }\n  return { ...structuredClone(profile), qualificationModel: requestedModel, reportedModelId: requestedModel };\n}\n\nfunction deepFreeze<T>(value: T): T {\n  if (typeof value !== \"object\" || value === null || Object.isFrozen(value))\n    return value;\n  Object.freeze(value);\n  for (const child of Object.values(value)) deepFreeze(child);\n  return value;\n}\n","sourceCodeStart":73,"sourceCodeEnd":105,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/acpx/qualified-profiles.ts#L73-L105","documentation":"Qualified ACPX agent profiles other than 'claude' are pinned: the requested model must exactly equal the profile's qualificationModel. If it differs, resolveQualifiedAcpxProfile throws with the expected model and the received value. Only the claude profile accepts an arbitrary non-empty model.","triggerScenarios":"Calling resolveQualifiedAcpxProfile(agent, requestedModel) (or any caller: qualifiedProfile, profile, parseOpenParams, evalSessionProviderVersion, runEvalSessionCli, validateAcpxDriverConfig) where agent is a non-claude qualified agent and requestedModel !== QUALIFIED_ACPX_PROFILES[agent].qualificationModel.","commonSituations":"Typo or alias in the model id (e.g. missing a date suffix); newer/older model versions from a changelog not matching the qualified pin; copy-pasting a model id from another provider; a config template using a different default model.","solutions":["Read the expected model from the error message and set requestedModel to exactly profile.qualificationModel for that agent.","Use the 'claude' profile if you need arbitrary model ids — it is the only profile with a free-form model.","Check QUALIFIED_ACPX_PROFILES in packages/paperclip-runner/src/drivers/acpx/qualified-profiles.ts for the current pinned ids after upgrading the runner package.","If a new model version should be qualified, update the profile's qualificationModel in code (or upgrade the package) rather than overriding the string at call sites."],"exampleFix":"// before\nresolveQualifiedAcpxProfile(\"codex\", \"gpt-5.1\"); // wrong pin\n// after\nresolveQualifiedAcpxProfile(\"codex\", \"gpt-5.1-codex\"); // matches qualificationModel","handlingStrategy":"validation","validationCode":"import { QUALIFIED_ACPX_PROFILES } from \"@paperclip/paperclip-runner/drivers/acpx/qualified-profiles\";\nif (agent !== \"claude\" && model !== QUALIFIED_ACPX_PROFILES[agent].qualificationModel) {\n  throw new Error(`${agent} requires model ${QUALIFIED_ACPX_PROFILES[agent].qualificationModel}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  resolveQualifiedAcpxProfile(agent, model);\n} catch (e) {\n  if (e.message.includes(\"requires exact model\")) {\n    // surface the expected model from the message to the user/config\n  }\n  throw e;\n}","preventionTips":["Source model ids from the profile definitions, not from free-form config, for non-claude agents.","Re-check pinned model ids after every runner package upgrade.","Avoid copy-pasting model ids across providers/agents."],"tags":["validation","config","model-id","acpx"],"backgroundTag":"invalid-argument-value","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}