{"record":{"id":"90d2772cbad51d75","repo":"nexu-io/open-design","slug":"cannot-overwrite-built-in-automation-template-te","errorCode":null,"errorMessage":"cannot overwrite built-in automation template ${template.id}","messagePattern":"cannot overwrite built-in automation template (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/daemon/src/automation-templates.ts","lineNumber":328,"sourceCode":"    ...BUILT_IN_AUTOMATION_TEMPLATES,\n    ...userTemplates.filter((template) => !builtInIds.has(template.id)),\n  ];\n}\n\nexport async function getAnyAutomationTemplate(\n  dataDir: string,\n  id: string,\n): Promise<AutomationTemplate | null> {\n  return (await listAllAutomationTemplates(dataDir)).find((template) => template.id === id) ?? null;\n}\n\nexport async function upsertUserAutomationTemplate(\n  dataDir: string,\n  input: unknown,\n): Promise<AutomationTemplate> {\n  const template = normalizeAutomationTemplate(input);\n  if (BUILT_IN_AUTOMATION_TEMPLATES.some((builtIn) => builtIn.id === template.id)) {\n    throw new Error(`cannot overwrite built-in automation template ${template.id}`);\n  }\n  const current = await readUserAutomationTemplates(dataDir);\n  const next = current.filter((existing) => existing.id !== template.id);\n  next.push(template);\n  next.sort((a, b) => a.id.localeCompare(b.id));\n  await writeUserAutomationTemplates(dataDir, next);\n  return template;\n}\n","sourceCodeStart":310,"sourceCodeEnd":337,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/automation-templates.ts#L310-L337","documentation":"Thrown by upsertUserAutomationTemplate when the normalized template id collides with one of the six built-in templates: ingest-source-memory-tree, extract-design-system, crystallize-run-into-skill, connector-digest-design-context, compress-project-context, promote-artifact-style. Built-ins are curated and cannot be overwritten through the user upsert path.","triggerScenarios":"POSTing a user template whose id exactly matches a built-in; forking a built-in to customize it without renaming; re-importing an export that included built-in templates alongside user ones.","commonSituations":"An export/import flow that round-trips the full list (built-ins plus user templates) and tries to write the built-ins back; a user copying a built-in as a starting point and forgetting to rename.","solutions":["Rename the id to something unique, e.g. add a suffix ('extract-design-system-v2', 'myteam:compress-context').","Filter the payload against BUILT_IN_AUTOMATION_TEMPLATES (exported list) before upserting in bulk.","If you genuinely need to change built-in behavior, that requires a code change to automation-templates.ts, not an upsert."],"exampleFix":"// before\nawait upsertUserAutomationTemplate(dataDir, {\n  id: 'extract-design-system', // collides with built-in -> throws\n  /* ... */\n});\n\n// after\nawait upsertUserAutomationTemplate(dataDir, {\n  id: 'extract-design-system-custom',\n  /* ... */\n});","handlingStrategy":"validation","validationCode":"import { BUILT_IN_AUTOMATION_TEMPLATES } from './automation-templates.js';\nconst BUILT_IN_IDS = new Set(BUILT_IN_AUTOMATION_TEMPLATES.map(t => t.id));\nif (BUILT_IN_IDS.has(payload.id)) {\n  throw new Error(`Refusing to overwrite built-in template '${payload.id}'. Rename the id.`);\n}","typeGuard":"function isUserTemplateId(id: string, builtInIds: Set<string>): boolean {\n  return !builtInIds.has(id);\n}","tryCatchPattern":"try {\n  await upsertUserAutomationTemplate(dataDir, payload);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('cannot overwrite built-in automation template ')) {\n    return conflict('Pick a different id; built-in templates cannot be overwritten.');\n  }\n  throw err;\n}","preventionTips":["Namespace custom template ids (team prefix, version suffix) so they never collide with built-ins.","When round-tripping exports, filter out built-in ids before re-importing.","Changing built-in behavior requires editing automation-templates.ts — never an upsert."],"tags":["automation","conflict","built-in","templates"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}