{"record":{"id":"ecaf05c9eb5b0206","repo":"paperclipai/paperclip","slug":"missing-live-candidate-for-profile","errorCode":null,"errorMessage":"Missing live candidate for ${profile}","messagePattern":"Missing live candidate for (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/scripts/run-local-provider-smoke.mjs","lineNumber":251,"sourceCode":"\nlet failed = false;\ntry {\n  // Import only after the disposable homes are authoritative so no provider\n  // module can snapshot the developer's normal Paperclip or provider state.\n  const {\n    RUNNER_LIVE_CANDIDATE_SLOTS,\n    executeLiveRunnerWorkflow,\n    runnerWorkflowCase,\n  } = await import(\"../dist/eval/index.js\");\n  const candidates = new Map(\n    profiles.map((profile) => [\n      profile,\n      liveCandidate(profile, RUNNER_LIVE_CANDIDATE_SLOTS),\n    ]),\n  );\n  const credentialsByProfile = new Map();\n  for (const [profile, candidate] of candidates) {\n    if (!candidate) throw new Error(`Missing live candidate for ${profile}`);\n    const missingCredentials = [];\n    const profileCredentials = {};\n    for (const name of candidate.qualification.requiredEnvironment) {\n      const value = ambientEnvironment[name]?.trim();\n      if (value) profileCredentials[name] = value;\n      else missingCredentials.push(name);\n    }\n    if (missingCredentials.length > 0) {\n      throw new Error(\n        `${profile} requires ${missingCredentials.join(\", \")} in the smoke process environment`,\n      );\n    }\n    credentialsByProfile.set(profile, profileCredentials);\n  }\n  const providerCredentialNames = new Set(\n    [...credentialsByProfile.values()].flatMap((credentials) =>\n      Object.keys(credentials),\n    ),","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/scripts/run-local-provider-smoke.mjs#L233-L269","documentation":"For each selected profile the script resolves a live candidate via liveCandidate(profile, RUNNER_LIVE_CANDIDATE_SLOTS). If no candidate matches the profile's qualification slot, it throws this error naming the profile. This means the profile cannot be run live because no configured candidate supports it.","triggerScenarios":"Selecting a profile whose id has no entry in RUNNER_LIVE_CANDIDATE_SLOTS (or all entries fail liveCandidate's slot matching), e.g. a newly added profile in PROFILE_IDS without a corresponding live candidate slot.","commonSituations":"Adding a new smoke profile without registering its live candidate, or profile-id renames that left the slots map stale.","solutions":["Check RUNNER_LIVE_CANDIDATE_SLOTS in run-local-provider-smoke.mjs for the profile id and add/register a matching candidate slot if missing.","Run a different profile that has a registered live candidate (e.g. runner-acpx-claude).","If the profile id was renamed, update the slots map to use the new id."],"exampleFix":"// before\nRUNNER_LIVE_CANDIDATE_SLOTS = [{ profiles: [\"runner-acpx-claude\"], ... }]\n// after\nRUNNER_LIVE_CANDIDATE_SLOTS = [{ profiles: [\"runner-acpx-claude\", \"runner-new\"], ... }]","handlingStrategy":"validation","validationCode":"const slots = require('./run-local-provider-smoke.mjs'); // or read source\nif (!RUNNER_LIVE_CANDIDATE_SLOTS.some(s => s.profiles.includes(profile))) console.warn(`no live candidate for ${profile}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register a slot for every new profile id","Grep RUNNER_LIVE_CANDIDATE_SLOTS before adding profiles","Keep profile ids and slot keys in sync on renames"],"tags":["configuration","candidate-resolution","smoke-test"],"backgroundTag":"resource-not-found","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}