{"record":{"id":"ce8ce8b4148167ee","repo":"paperclipai/paperclip","slug":"spaceslug-must-be-64-characters-or-fewer","errorCode":null,"errorMessage":"spaceSlug must be 64 characters or fewer","messagePattern":"spaceSlug must be 64 characters or fewer","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugins/plugin-llm-wiki/src/wiki/core.ts","lineNumber":453,"sourceCode":"function requireString(value: unknown, name: string): string {\n  const field = stringField(value);\n  if (!field) throw new Error(`${name} is required`);\n  return field;\n}\n\nfunction normalizeWikiId(value: unknown): string {\n  return stringField(value) ?? DEFAULT_WIKI_ID;\n}\n\nexport function normalizeSpaceSlug(value: unknown): string {\n  const raw = stringField(value) ?? DEFAULT_SPACE_SLUG;\n  const normalized = raw\n    .trim()\n    .toLowerCase()\n    .replace(/[^a-z0-9]+/g, \"-\")\n    .replace(/^-+|-+$/g, \"\");\n  if (!normalized) throw new Error(\"spaceSlug is required\");\n  if (normalized.length > 64) throw new Error(\"spaceSlug must be 64 characters or fewer\");\n  return normalized;\n}\n\nasync function requirePaperclipIngestionPolicy(\n  ctx: PluginContext,\n  input: { companyId: string; wikiId: string; spaceSlug?: string | null },\n  purpose: PaperclipIngestionPolicyPurpose,\n  options: { requireEnabledProfile?: boolean } = {},\n): Promise<WikiSpace> {\n  const space = await resolveSpace(ctx, {\n    companyId: input.companyId,\n    wikiId: input.wikiId,\n    spaceSlug: input.spaceSlug,\n  });\n  const profile = await profileForSpace(ctx, input.companyId, space);\n  const decision = evaluatePaperclipProfilePolicy({\n    space,\n    profile,","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/plugins/plugin-llm-wiki/src/wiki/core.ts#L435-L471","documentation":"Thrown by normalizeSpaceSlug() when the normalized slug (after lowercasing, collapsing separators, and trimming hyphens) exceeds 64 characters. The 64-char cap keeps slugs URL-safe and consistent with the space id derivation downstream (stableSpaceId hashes the slug). This runs after the empty-check, so the slug is non-empty but too long.","triggerScenarios":"Passing a long space name or pre-slugified string whose normalized form is 65+ chars. Auto-generating a slug from a verbose title without truncation.","commonSituations":"User creates a space with a very long display name and the slug is derived verbatim. Copy-pasting a paragraph into the slug field. Imported data with unbounded slug strings.","solutions":["Shorten the input to keep the normalized slug at or below 64 characters.","Truncate before calling normalizeSpaceSlug() (and ideally strip on a word boundary to avoid trailing hyphens).","Validate slug length in the UI form before submission."],"exampleFix":"// before\nconst slug = normalizeSpaceSlug(veryLongTitle); // throws if normalized > 64 chars\n// after\nconst truncated = veryLongTitle.slice(0, 64);\nconst slug = normalizeSpaceSlug(truncated);","handlingStrategy":"validation","validationCode":"const MAX_SLUG = 64;\nfunction normalizeAndTruncate(raw: string): string {\n  const truncated = raw.slice(0, MAX_SLUG);\n  return normalizeSpaceSlug(truncated);\n}","typeGuard":"function slugWithinLimit(raw: string): boolean {\n  // optimistic: pre-truncate and re-measure\n  const n = raw.trim().toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\");\n  return n.length <= 64;\n}","tryCatchPattern":"try {\n  slug = normalizeSpaceSlug(longInput);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"64 characters\")) {\n    slug = normalizeSpaceSlug(longInput.slice(0, 64));\n  } else throw err;\n}","preventionTips":["Truncate user input to <= 64 chars before slugifying.","Show a live character counter in the space-name form.","Avoid deriving slugs from unbounded free-text fields."],"tags":["llm-wiki","validation","slug","length-limit"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}