paperclipai/paperclip · error · Error
Paperclip ingestion profile sources exceed the hard cap of $
Error message
Paperclip ingestion profile sources exceed the hard cap of ${MAX_PAPERCLIP_INGESTION_PROFILE_SOURCE_COUNT}. What it means
Thrown by validatePaperclipIngestionProfile() when profile.sourceScopes.length exceeds MAX_PAPERCLIP_INGESTION_PROFILE_SOURCE_COUNT (= 3, defined at core.ts:32). This is a hard cap on the number of source scopes per profile to bound ingestion fan-out. (Same code at line 995; error 478 is the duplicate occurrence.)
Source
Thrown at packages/plugins/plugin-llm-wiki/src/wiki/core.ts:995
}
async function validatePaperclipIngestionProfile(ctx: PluginContext, input: {
companyId: string;
space: WikiSpace;
profile: PaperclipIngestionProfileV1;
}) {
const policy = evaluatePaperclipProfilePolicy({
space: input.space,
profile: input.profile,
purpose: "profile_update",
requireEnabledProfile: input.profile.enabled && input.space.slug !== DEFAULT_SPACE_SLUG,
});
if (!policy.allowed) throw new Error(policy.message);
if (input.profile.enabled && input.profile.sourceScopes.length === 0) {
throw new Error("Paperclip ingestion profile must include at least one source scope before it can be enabled.");
}
if (input.profile.sourceScopes.length > MAX_PAPERCLIP_INGESTION_PROFILE_SOURCE_COUNT) {
throw new Error(`Paperclip ingestion profile sources exceed the hard cap of ${MAX_PAPERCLIP_INGESTION_PROFILE_SOURCE_COUNT}.`);
}
for (const scope of input.profile.sourceScopes) {
if (scope.kind === "company_all" && input.space.slug !== DEFAULT_SPACE_SLUG) {
throw new Error("Everything in the company is only available on the default wiki space.");
}
if (scope.kind === "selected_projects") {
if (scope.projectIds.length > MAX_PAPERCLIP_PROFILE_SELECTED_PROJECTS) {
throw new Error(`selected_projects exceeds the hard cap of ${MAX_PAPERCLIP_PROFILE_SELECTED_PROJECTS}.`);
}
for (const projectId of scope.projectIds) {
const project = await ctx.projects.get(projectId, input.companyId);
if (!project) throw new Error(`Project belongs to another company or does not exist: ${projectId}`);
}
}
if (scope.kind === "root_issues") {
if (scope.issueIds.length > MAX_PAPERCLIP_PROFILE_ROOT_ISSUES) {
throw new Error(`root_issues exceeds the hard cap of ${MAX_PAPERCLIP_PROFILE_ROOT_ISSUES}.`);
}View on GitHub (pinned to 67001ec6eb)
Solutions
- Reduce the number of source scopes to 3 or fewer (use company_all on the default space to cover many at once).
- Deduplicate overlapping scopes (e.g. merge selected_projects entries).
- Split ingestion across multiple profiles/spaces if more coverage is genuinely needed.
Example fix
// before profile.sourceScopes = [s1, s2, s3, s4]; // 4 > 3 // after profile.sourceScopes = [s1, s2, s3];
Defensive patterns
Strategy: validation
Validate before calling
const MAX_PROFILE_SOURCES = 3;
function assertScopeCount(profile: { sourceScopes: unknown[] }) {
if (profile.sourceScopes.length > MAX_PROFILE_SOURCES) {
throw new Error(`sourceScopes exceeds cap of ${MAX_PROFILE_SOURCES}`);
}
} Type guard
function withinSourceCap(profile: { sourceScopes: unknown[] }, cap = 3): boolean {
return profile.sourceScopes.length <= cap;
} Try / catch
try {
await validatePaperclipIngestionProfile(ctx, { companyId, space, profile });
} catch (err) {
if (err instanceof Error && err.message.includes("exceed the hard cap")) {
profile.sourceScopes = profile.sourceScopes.slice(0, 3); // then retry
} else throw err;
} Prevention
- Cap the scope-add UI at 3 entries.
- Dedupe overlapping scopes before submission.
- Use company_all on the default space to consolidate coverage.
When it happens
Trigger: Submitting a profile with 4 or more source scopes. Aggregating scopes from multiple legacy profiles during migration.
Common situations: UI that lets users add unlimited scopes. Merging profiles without deduping. Per-team or per-project scope explosion.
Related errors
- ${name} exceeds the hard Paperclip ingestion cap of ${max} c
- ${policy.message}
- Paperclip ingestion profile must include at least one source
- Everything in the company is only available on the default w
- ${decision.message}
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/85905be2a90742c2.
Report an issue: GitHub.