paperclipai/paperclip · error · Error
Invalid PAPERCLIP_PAGE_DEFAULT_PREFIX: use lowercase path…
Error message
Invalid PAPERCLIP_PAGE_DEFAULT_PREFIX: use lowercase path segments without leading or trailing slashes
What it means
announcementPublishPrefix validates the optional PAPERCLIP_PAGE_DEFAULT_PREFIX host prefix against /^[a-z0-9-]+(?:\/[a-z0-9-]+)*$/ — lowercase alphanumeric-and-hyphen segments separated by single slashes, with no leading or trailing slash. An invalid value throws this error before any publishing happens.
Solutions
- Rewrite the prefix as lowercase path segments, e.g. 'pages/team-a' instead of '/Pages/Team-A/'.
- Remove leading and trailing slashes from the env value.
- Replace invalid characters (underscores, dots, spaces) with hyphens.
- Leave PAPERCLIP_PAGE_DEFAULT_PREFIX unset to use the default 'announcements/v1' prefix.
Example fix
// before PAPERCLIP_PAGE_DEFAULT_PREFIX=/Announcements/ // after PAPERCLIP_PAGE_DEFAULT_PREFIX=announcements
Defensive patterns
Strategy: validation
Validate before calling
const prefix = process.env.PAPERCLIP_PAGE_DEFAULT_PREFIX;
if (prefix !== undefined && !/^[a-z0-9-]+(?:\/[a-z0-9-]+)*$/.test(prefix)) {
throw new Error(`Bad PAPERCLIP_PAGE_DEFAULT_PREFIX: ${prefix}`);
} Type guard
const isValidPrefix = (p) => p === undefined || /^[a-z0-9-]+(?:\/[a-z0-9-]+)*$/.test(p);
Try / catch
try {
const prefix = announcementPublishPrefix(staging, hostPrefix);
} catch (e) {
if (String(e.message).includes('PAPERCLIP_PAGE_DEFAULT_PREFIX')) {
console.error('Fix the env var: lowercase [a-z0-9-] segments, no leading/trailing slashes.');
process.exit(1);
}
throw e;
} Prevention
- Validate the env var in CI before running publish jobs.
- Never include slashes at the start/end of the prefix value.
- Use only lowercase letters, digits, and hyphens; no underscores or dots.
- Document the expected format next to the secret/variable definition.
When it happens
Trigger: Calling announcementPublishPrefix (or the publish-announcements CLI) with hostPrefix containing uppercase letters, underscores, dots, leading/trailing slashes, empty segments ('//'), or other characters outside [a-z0-9-].
Common situations: Setting PAPERCLIP_PAGE_DEFAULT_PREFIX='/announcements' or 'My/Prefix' in CI secrets or .env; copying a URL with scheme into the prefix; using a trailing slash out of habit.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- ACPX profile requires exact model ; received
- ACPX model must not be empty
- ACPX provider identity contains an invalid permission mode
- ACPX provider identity contains invalid lifetime fences
- ACPX runtime directory must be a directory
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/4bb7cdf71df84535.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/publish-announcements.ts:13
#!/usr/bin/env -S node --import tsx
import { execFileSync } from "node:child_process";
import { createHash } from "node:crypto";
import { lstat, readFile } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { ANNOUNCEMENT_ANIMATION_MAX_BYTES, ANNOUNCEMENT_IMAGE_MAX_BYTES, ANNOUNCEMENT_MANIFEST_MAX_BYTES, announcementIdSchema, announcementManifestSchema } from "../packages/shared/src/announcements.js";
import { validateAnnouncementAnimation } from "../server/src/services/announcement-animation.js";
export function announcementPublishPrefix(staging?: string, hostPrefix?: string) {
if (hostPrefix !== undefined && !/^[a-z0-9-]+(?:\/[a-z0-9-]+)*$/.test(hostPrefix)) {
throw new Error("Invalid PAPERCLIP_PAGE_DEFAULT_PREFIX: use lowercase path segments without leading or trailing slashes");
}
const prefix = staging === undefined ? "announcements/v1" : `announcements/staging/${announcementIdSchema.parse(staging)}/v1`;
return hostPrefix ? `${hostPrefix}/${prefix}` : prefix;
}
export function parseAnnouncementPublishArgs(args: string[]) {
let sourceDirectory: string | undefined;
let staging: string | undefined;
let mode: "publish" | "dry-run" | undefined;
const usage = "Usage: publish-announcements.ts [directory] [--staging name] [--dry-run | --publish]";
for (let index = 0; index < args.length; index++) {
const arg = args[index];
if (arg === "--publish" || arg === "--dry-run") {
if (mode) throw new Error(usage);
mode = arg === "--publish" ? "publish" : "dry-run";
} else if (arg === "--staging") {
if (staging !== undefined || !args[index + 1]) throw new Error(usage);
staging = announcementIdSchema.parse(args[++index]);View on GitHub (pinned to 3f1d897a7c)