{"record":{"id":"1a8afa19ff1d51e6","repo":"Budibase/budibase","slug":"automations-cannot-have-more-than-max-sticky-not","errorCode":null,"errorMessage":"Automations cannot have more than ${MAX_STICKY_NOTES_PER_AUTOMATION} sticky notes","messagePattern":"Automations cannot have more than (.+?) sticky notes","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/automations/crud.ts","lineNumber":322,"sourceCode":"      const readonlyField = key as keyof typeof step.inputs\n      const oldStep = oldStepDefinitions.find(i => i.id === step.id)\n      if (step.inputs[readonlyField] !== oldStep?.inputs[readonlyField]) {\n        throw new HTTPError(\n          `Field ${readonlyField} is readonly and it cannot be modified`,\n          400\n        )\n      }\n    })\n  }\n}\n\nfunction validateStickyNoteLimit(automation: Automation) {\n  const stickyNotes = automation.uiTree?.stickyNotes\n  if (\n    Array.isArray(stickyNotes) &&\n    stickyNotes.length > MAX_STICKY_NOTES_PER_AUTOMATION\n  ) {\n    throw new HTTPError(\n      `Automations cannot have more than ${MAX_STICKY_NOTES_PER_AUTOMATION} sticky notes`,\n      400\n    )\n  }\n}\n\nfunction trimUnexpectedObjectFields<T extends Automation>(automation: T): T {\n  // This will ensure all the automation fields (and nothing else) is mapped to the result\n  const allRequired: RequiredKeys<Omit<Automation, \"_deleted\">> = {\n    _id: automation._id,\n    _rev: automation._rev,\n    definition: automation.definition,\n    screenId: automation.screenId,\n    uiTree: automation.uiTree,\n    appId: automation.appId,\n    live: automation.live,\n    projectIds: automation.projectIds,\n    name: automation.name,","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/automations/crud.ts#L304-L340","documentation":"Automations support UI sticky notes, capped at MAX_STICKY_NOTES_PER_AUTOMATION. validateStickyNoteLimit runs on both create and update and throws this 400 HTTPError when automation.uiTree.stickyNotes exceeds the limit.","triggerScenarios":"Creating or updating an automation whose uiTree.stickyNotes array length is greater than MAX_STICKY_NOTES_PER_AUTOMATION.","commonSituations":"Bulk import/paste of an automation JSON with many notes; automation copy/duplicate accumulating notes; older clients without the limit create oversized canvases that now fail to save.","solutions":["Remove sticky notes until the count is at or below MAX_STICKY_NOTES_PER_AUTOMATION and retry.","Consolidate overlapping notes into fewer notes before saving.","If importing, strip or trim the stickyNotes array from the imported JSON."],"exampleFix":"// before\nautomation.uiTree.stickyNotes = [...manyNotes] // > limit\nawait update(automation)\n// after\nautomation.uiTree.stickyNotes = automation.uiTree.stickyNotes.slice(0, MAX_STICKY_NOTES_PER_AUTOMATION)\nawait update(automation)","handlingStrategy":"validation","validationCode":"const MAX = MAX_STICKY_NOTES_PER_AUTOMATION\nif (Array.isArray(automation.uiTree?.stickyNotes) && automation.uiTree.stickyNotes.length > MAX) {\n  automation.uiTree.stickyNotes = automation.uiTree.stickyNotes.slice(0, MAX)\n}\nawait sdk.automations.update(automation)","typeGuard":null,"tryCatchPattern":"try {\n  await sdk.automations.update(automation)\n} catch (e) {\n  if (e instanceof HTTPError && e.status === 400 && e.message.includes(\"sticky notes\")) {\n    // trim stickyNotes and retry / inform the user of the cap\n  }\n  throw e\n}","preventionTips":["Cap sticky note creation in the UI at MAX_STICKY_NOTES_PER_AUTOMATION","Trim stickyNotes when importing/copying automations","Consolidate notes before hitting the cap"],"tags":["validation","automations","limit","bad-request"],"backgroundTag":"resource-limit-exceeded","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}