{"record":{"id":"85905be2a90742c2","repo":"paperclipai/paperclip","slug":"paperclip-ingestion-profile-sources-exceed-the-har","errorCode":null,"errorMessage":"Paperclip ingestion profile sources exceed the hard cap of ${MAX_PAPERCLIP_INGESTION_PROFILE_SOURCE_COUNT}.","messagePattern":"Paperclip ingestion profile sources exceed the hard cap of (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugins/plugin-llm-wiki/src/wiki/core.ts","lineNumber":995,"sourceCode":"}\n\nasync function validatePaperclipIngestionProfile(ctx: PluginContext, input: {\n  companyId: string;\n  space: WikiSpace;\n  profile: PaperclipIngestionProfileV1;\n}) {\n  const policy = evaluatePaperclipProfilePolicy({\n    space: input.space,\n    profile: input.profile,\n    purpose: \"profile_update\",\n    requireEnabledProfile: input.profile.enabled && input.space.slug !== DEFAULT_SPACE_SLUG,\n  });\n  if (!policy.allowed) throw new Error(policy.message);\n  if (input.profile.enabled && input.profile.sourceScopes.length === 0) {\n    throw new Error(\"Paperclip ingestion profile must include at least one source scope before it can be enabled.\");\n  }\n  if (input.profile.sourceScopes.length > MAX_PAPERCLIP_INGESTION_PROFILE_SOURCE_COUNT) {\n    throw new Error(`Paperclip ingestion profile sources exceed the hard cap of ${MAX_PAPERCLIP_INGESTION_PROFILE_SOURCE_COUNT}.`);\n  }\n  for (const scope of input.profile.sourceScopes) {\n    if (scope.kind === \"company_all\" && input.space.slug !== DEFAULT_SPACE_SLUG) {\n      throw new Error(\"Everything in the company is only available on the default wiki space.\");\n    }\n    if (scope.kind === \"selected_projects\") {\n      if (scope.projectIds.length > MAX_PAPERCLIP_PROFILE_SELECTED_PROJECTS) {\n        throw new Error(`selected_projects exceeds the hard cap of ${MAX_PAPERCLIP_PROFILE_SELECTED_PROJECTS}.`);\n      }\n      for (const projectId of scope.projectIds) {\n        const project = await ctx.projects.get(projectId, input.companyId);\n        if (!project) throw new Error(`Project belongs to another company or does not exist: ${projectId}`);\n      }\n    }\n    if (scope.kind === \"root_issues\") {\n      if (scope.issueIds.length > MAX_PAPERCLIP_PROFILE_ROOT_ISSUES) {\n        throw new Error(`root_issues exceeds the hard cap of ${MAX_PAPERCLIP_PROFILE_ROOT_ISSUES}.`);\n      }","sourceCodeStart":977,"sourceCodeEnd":1013,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/plugins/plugin-llm-wiki/src/wiki/core.ts#L977-L1013","documentation":"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.)","triggerScenarios":"Submitting a profile with 4 or more source scopes. Aggregating scopes from multiple legacy profiles during migration.","commonSituations":"UI that lets users add unlimited scopes. Merging profiles without deduping. Per-team or per-project scope explosion.","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."],"exampleFix":"// before\nprofile.sourceScopes = [s1, s2, s3, s4]; // 4 > 3\n// after\nprofile.sourceScopes = [s1, s2, s3];","handlingStrategy":"validation","validationCode":"const MAX_PROFILE_SOURCES = 3;\nfunction assertScopeCount(profile: { sourceScopes: unknown[] }) {\n  if (profile.sourceScopes.length > MAX_PROFILE_SOURCES) {\n    throw new Error(`sourceScopes exceeds cap of ${MAX_PROFILE_SOURCES}`);\n  }\n}","typeGuard":"function withinSourceCap(profile: { sourceScopes: unknown[] }, cap = 3): boolean {\n  return profile.sourceScopes.length <= cap;\n}","tryCatchPattern":"try {\n  await validatePaperclipIngestionProfile(ctx, { companyId, space, profile });\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"exceed the hard cap\")) {\n    profile.sourceScopes = profile.sourceScopes.slice(0, 3); // then retry\n  } else throw err;\n}","preventionTips":["Cap the scope-add UI at 3 entries.","Dedupe overlapping scopes before submission.","Use company_all on the default space to consolidate coverage."],"tags":["llm-wiki","profile","limit","paperclip"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}