paperclipai/paperclip · error · Error
Wiki page writes must target AGENTS.md, IDEA.md, or wiki/: $
Error message
Wiki page writes must target AGENTS.md, IDEA.md, or wiki/: ${path} What it means
Thrown by assertPagePath after assertWikiPath succeeds, when the normalized path is not index.md, log.md, WICKI.md, AGENTS.md, IDEA.md, or under wiki/. It restricts markdown page writes to page-eligible locations (raw/ is intentionally excluded).
Source
Thrown at packages/plugins/plugin-llm-wiki/src/wiki/core.ts:1185
trimmed !== ".gitignore" &&
trimmed !== "WIKI.md" &&
trimmed !== "AGENTS.md" &&
trimmed !== "IDEA.md" &&
trimmed !== "index.md" &&
trimmed !== "log.md" &&
!trimmed.startsWith("raw/") &&
!trimmed.startsWith("wiki/") &&
!(options.allowMetadata && trimmed.startsWith(".paperclip/"))
) {
throw new Error(`Wiki path must stay inside AGENTS.md, IDEA.md, raw/, or wiki/: ${path}`);
}
return trimmed;
}
function assertPagePath(path: string): string {
const normalized = assertWikiPath(path);
if (normalized !== "index.md" && normalized !== "log.md" && normalized !== "WIKI.md" && normalized !== "AGENTS.md" && normalized !== "IDEA.md" && !normalized.startsWith("wiki/")) {
throw new Error(`Wiki page writes must target AGENTS.md, IDEA.md, or wiki/: ${path}`);
}
if (!normalized.endsWith(".md")) {
throw new Error(`Wiki page path must be a markdown file: ${path}`);
}
return normalized;
}
function assertPageWriteAllowed(path: string, writer: WritePageInput["writer"] = "agent_tool"): void {
if (writer !== "board_ui" && PROTECTED_WIKI_CONTROL_FILES.has(path)) {
throw new Error(`Refusing to overwrite protected wiki control file ${path}; board-managed edits must use the wiki UI.`);
}
}
function assertRawPath(path: string): string {
const normalized = assertWikiPath(path);
if (!normalized.startsWith("raw/")) {
throw new Error(`Source path must stay inside raw/: ${path}`);
}View on GitHub (pinned to 67001ec6eb)
Solutions
- For markdown pages, target wiki/<name>.md or the control files (AGENTS.md, IDEA.md, WIKI.md, index.md, log.md).
- For raw assets, use the raw-source write API (assertRawPath) so the path lands under raw/.
- Validate the intended path against the page allowlist before calling writePage.
Example fix
// before
await writePage(ctx, { companyId, path: "raw/notes.md" });
// after
await writeRawSource(ctx, { companyId, path: "raw/notes.md" });
// or for a page:
await writePage(ctx, { companyId, path: "wiki/notes.md" }); Defensive patterns
Strategy: validation
Validate before calling
const PAGE_ALLOWED = new Set(["index.md", "log.md", "WIKI.md", "AGENTS.md", "IDEA.md"]);
function sanitizePagePath(path) {
const t = String(path).trim().replace(/^\/+/, "");
if (!PAGE_ALLOWED.has(t) && !t.startsWith("wiki/")) {
throw new Error(`Wiki page writes must target AGENTS.md, IDEA.md, or wiki/: ${path}`);
}
return t;
} Type guard
function isPagePath(path) {
const t = String(path ?? "").trim().replace(/^\/+/, "");
return PAGE_ALLOWED.has(t) || t.startsWith("wiki/");
} Try / catch
try {
await writePage(ctx, { companyId, path, content });
} catch (err) {
if (/page writes must target/.test(err.message)) {
path = path.startsWith("raw/") ? path.replace(/^raw\//, "wiki/") : `wiki/${path}`;
return writePage(ctx, { companyId, path, content });
}
throw err;
} Prevention
- Use wiki/ for page content; use raw/ via the raw-source API for assets.
- Do not route non-page files through writePage.
- Validate the page allowlist at the boundary.
When it happens
Trigger: Calling a page-write API (writePage) with a path under raw/ or with a non-page top-level file like '.gitignore'.
Common situations: Using the page API to write a raw asset by mistake; routing a binary or source file through the page writer; misclassifying a raw/ asset as a wiki page.
Related errors
- Wiki page path must be a markdown file: ${path}
- Source path must stay inside raw/: ${path}
- selected_projects exceeds the hard cap of ${MAX_PAPERCLIP_PR
- Project belongs to another company or does not exist: ${proj
- root_issues exceeds the hard cap of ${MAX_PAPERCLIP_PROFILE_
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/01bcc181a3f71149.
Report an issue: GitHub.