paperclipai/paperclip · error · Error
Roster selection must contain unique comma-separated IDs
Error message
Roster selection must contain unique comma-separated IDs
What it means
parseRosterSelection parses a comma-separated list of roster IDs and requires the list to be non-empty after trimming and free of duplicates. It backs the --rosters style selection flag for the eval campaign. Empty, all-duplicate, or malformed selections are rejected.
Source
Thrown at packages/paperclip-runner/scripts/runner-protocol-eval-campaign.mjs:81
}
if (config.provider === "acpx") {
if (config.acpxAgent === "pi") return "OPENROUTER_API_KEY";
if (config.acpxAgent === "claude") return "ANTHROPIC_API_KEY";
if (config.acpxAgent === "codex") return "OPENAI_API_KEY";
}
throw new Error(
`No credential policy for ${config.provider ?? "codex"}/${config.acpxAgent ?? "default"}`,
);
}
function parseRosterSelection(value) {
if (!value?.trim() || value.trim() === "all") return null;
const selected = value
.split(",")
.map((entry) => entry.trim())
.filter(Boolean);
if (selected.length === 0 || new Set(selected).size !== selected.length) {
throw new Error("Roster selection must contain unique comma-separated IDs");
}
return new Set(selected);
}
async function maintainedRosterSelection(programRoot) {
const campaignPath = resolve(programRoot, "campaigns/live-direct-full.json");
const campaign = await loadObject(campaignPath);
if (
campaign.schema !== "paperclip-runner/live-campaign/v1" ||
!Array.isArray(campaign.lanes)
) {
throw new Error(`Unsupported live campaign schema in ${campaignPath}`);
}
const selected = campaign.lanes
.filter((lane) => lane.executionClass !== "disabled")
.map((lane) => {
const rosterPath = inside(
programRoot,View on GitHub (pinned to 01ad858492)
Solutions
- Remove duplicate IDs from the comma-separated list.
- Ensure at least one non-empty ID remains after the commas.
- Use 'all' (or omit the flag) to select the maintained roster set instead of listing IDs.
Example fix
// before node runner-protocol-eval-campaign.mjs --rosters "codex-core,codex-core" // after node runner-protocol-eval-campaign.mjs --rosters "codex-core,claude-core"
Defensive patterns
Strategy: validation
Validate before calling
const entries = value.split(",").map((s) => s.trim()).filter(Boolean);
if (entries.length === 0 || new Set(entries).size !== entries.length) throw new Error("Roster selection must be unique, comma-separated IDs"); Type guard
const isValidSelection = (v) => {
if (typeof v !== "string") return false;
const entries = v.split(",").map((s) => s.trim()).filter(Boolean);
return entries.length > 0 && new Set(entries).size === entries.length;
}; Try / catch
try {
const selection = parseRosterSelection(argv.rosters);
} catch (err) {
if (err.message.includes("unique comma-separated")) console.error("Pass each roster ID once, e.g. --rosters a,b,c");
throw err;
} Prevention
- Deduplicate and trim the roster list before building the CLI flag in scripts.
- Prefer 'all' or omitting the flag when you want the maintained set.
- Keep a canonical list of roster IDs in one place and derive flags from it.
When it happens
Trigger: Passing a selection value like 'r1,r1', 'r1,,r1' (dedupes to unique so fine, but '' entries filtered — duplicates still counted on raw trimmed list), or a value that trims to nothing but isn't empty/'all', e.g. passing ' ' with extra content or 'r1,' with duplicates elsewhere.
Common situations: CLI flag typed as --rosters 'a,a'; scripted invocation building the list from a source with repeated IDs; pasting a list that already contains the same roster twice.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- --model must be the qualified Managed Agents model ${CLAUDE_
- --api-key-secret-id must be a UUID
- --max-session-list-cost-usd must resolve to at least one cen
- unknown argument: ${args[index] ?? ""}
- OpenCode test drives require --model openrouter/<model>, wit
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/3d0e04775ace5e2c.
Report an issue: GitHub.