paperclipai/paperclip · error · Error
${policy.message}
Error message
${policy.message} What it means
Thrown by validatePaperclipIngestionProfile() when evaluatePaperclipProfilePolicy() denies a profile_update. The message is the policy's own message, naming the reason (archived_space, restricted_space, profile_disabled, profile_empty). Note requireEnabledProfile here is computed as profile.enabled && space.slug !== default, so enabling a profile on a non-default space with no source scopes triggers profile_empty.
Source
Thrown at packages/plugins/plugin-llm-wiki/src/wiki/core.ts:990
for (const key of profile.sourceScopes.flatMap(scopeIdentity)) {
if (own.has(key)) overlaps += 1;
}
}
return overlaps;
}
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}`);
}View on GitHub (pinned to 67001ec6eb)
Solutions
- Read policy.message to identify the reason and address it (un-archive, set accessScope=shared, add a source scope, or disable the profile before saving).
- If enabling, ensure at least one source scope is configured first (see error 475).
- Use the default space to bypass the enabled-profile gate during initial setup.
Example fix
// before
await validatePaperclipIngestionProfile(ctx, { companyId, space: customSpace, profile: { enabled: true, sourceScopes: [], ... } });
// after
await validatePaperclipIngestionProfile(ctx, { companyId, space: customSpace, profile: { enabled: true, sourceScopes: [{ kind: "selected_projects", projectIds: ["p1"] }], ... } }); Defensive patterns
Strategy: validation
Validate before calling
const profile = await getPaperclipIngestionProfile(ctx, { companyId, wikiId, spaceSlug });
if (profile.effectiveState === "policy_blocked") {
throw new Error(`Profile update blocked: ${profile.policyBlocks.join("; ")}`);
} Type guard
function isProfileUpdatable(p: { effectiveState: string }): boolean {
return p.effectiveState !== "policy_blocked";
} Try / catch
try {
await validatePaperclipIngestionProfile(ctx, { companyId, space, profile });
} catch (err) {
if (err instanceof Error && err.message.startsWith("Paperclip ingestion policy denied")) {
// read reason, un-archive space / set shared / add scopes, then retry
} else throw err;
} Prevention
- Check policyBlocks via getPaperclipIngestionProfile() before updating.
- Ensure the target space is active and shared before profile edits.
- Add at least one source scope before enabling on a non-default space.
When it happens
Trigger: Updating a profile on an archived or non-shared space. Enabling a profile on a custom space, or submitting a profile with enabled=true but zero sourceScopes on a non-default space.
Common situations: UI 'Enable' toggle clicked before any source scope added. Profile update sent for a space that was archived concurrently. Access scope changed to private mid-session.
Related errors
- ${decision.message}
- Paperclip ingestion profile must include at least one source
- Paperclip ingestion profile sources exceed the hard cap of $
- Everything in the company is only available on the default w
- Paperclip source scope must specify either projectId or root
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/6c6da14e819eaeb1.
Report an issue: GitHub.