paperclipai/paperclip · error · Error
Wiki page path must be a markdown file: ${path}
Error message
Wiki page path must be a markdown file: ${path} What it means
Thrown by assertPagePath when the normalized path passes the location check but does not end with '.md'. Enforces that page writes are markdown only.
Source
Thrown at packages/plugins/plugin-llm-wiki/src/wiki/core.ts:1188
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}`);
}
return normalized;
}
View on GitHub (pinned to 67001ec6eb)
Solutions
- Append '.md' to the filename before calling writePage.
- Route non-markdown content to the raw-source API under raw/ instead.
- Validate the extension at the form boundary.
Example fix
// before
await writePage(ctx, { companyId, path: "wiki/notes" });
// after
await writePage(ctx, { companyId, path: "wiki/notes.md" }); Defensive patterns
Strategy: validation
Validate before calling
function ensureMarkdownExtension(path) {
const t = String(path).trim().replace(/^\/+/, "");
if (!t.endsWith(".md")) throw new Error(`Wiki page path must be a markdown file: ${path}`);
return t;
} Type guard
function isMarkdownPath(path) {
return String(path ?? "").trim().replace(/^\/+/, "").endsWith(".md");
} Try / catch
try {
await writePage(ctx, { companyId, path, content });
} catch (err) {
if (/must be a markdown file/.test(err.message)) {
return writePage(ctx, { companyId, path: `${path}.md`, content });
}
throw err;
} Prevention
- Always append .md when constructing page paths.
- Route non-markdown content to raw/.
- Validate extension at the form boundary.
When it happens
Trigger: Calling writePage with a path like 'wiki/notes.txt', 'wiki/index', or 'wiki/data.json'.
Common situations: Forgetting the extension; importing a non-markdown file via the page API; auto-generated path missing its suffix.
Related errors
- Wiki page writes must target AGENTS.md, IDEA.md, or wiki/: $
- 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/16ed8d9304f39975.
Report an issue: GitHub.