{"record":{"id":"86864a271fc4232a","repo":"Budibase/budibase","slug":"tool-name-must-be-under-64-characters-long","errorCode":null,"errorMessage":"Tool name must be under 64 characters long","messagePattern":"Tool name must be under 64 characters long","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/pro/src/ai/utils.ts","lineNumber":6,"sourceCode":"import { SupportedFileType } from \"@budibase/types\"\n\n// tool names must align with regex \"^[a-zA-Z0-9_-]+$\"\nexport function sanitiseToolName(name: string) {\n  if (name.length > 64) {\n    throw new Error(\"Tool name must be under 64 characters long\")\n  }\n  return name.replace(/[^a-zA-Z0-9_-]/g, \"_\")\n}\n\nexport function normalizeContentType(contentType?: string): string {\n  if (!contentType) {\n    return \"application/octet-stream\"\n  }\n\n  // If it's already a proper MIME type, return it\n  if (contentType.includes(\"/\")) {\n    return contentType\n  }\n\n  // Map SupportedFileType values to proper MIME types\n  const mimeTypeMap: Record<string, string> = {\n    [SupportedFileType.PDF]: \"application/pdf\",\n    [SupportedFileType.JPG]: \"image/jpeg\",","sourceCodeStart":1,"sourceCodeEnd":24,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/pro/src/ai/utils.ts#L1-L24","documentation":"sanitiseToolName enforces LLM tool-name constraints: names must match ^[a-zA-Z0-9_-]+$ and be at most 64 characters. It sanitizes illegal characters to underscores but throws outright if the name exceeds 64 characters because truncation could collide or break mapping to the original tool.","triggerScenarios":"Registering an AI tool whose derived name (e.g. from a table, datasource, query, or automation name) exceeds 64 characters — long resource names get concatenated into tool identifiers and blow the limit.","commonSituations":"Very long datasource/query names combined with prefixes like \"query_\" or \"table_\"; SCIM-synced or imported resources with long names; other providers (OpenAI/Anthropic) then reject the tool at the API level if the check were skipped.","solutions":["Shorten the underlying resource name (table/query/datasource/automation) to keep the derived tool name under 64 chars.","Truncate or hash the tool name before calling sanitiseToolName, keeping a mapping back to the full id.","Add pre-validation in the UI/API that warns when a resource name will exceed the tool-name limit."],"exampleFix":"// before\nconst name = sanitiseToolName(`table_${table.name}`) // may exceed 64\n// after\nconst raw = `table_${table.name}`\nconst name = sanitiseToolName(raw.length > 64 ? `table_${raw.slice(6, 60)}_${hash(table.id)}` : raw)","handlingStrategy":"validation","validationCode":"if (`table_${name}`.length > 64) throw new Error(`Resource name \"${name}\" is too long for AI tool registration (max 64 incl. prefix)`)","typeGuard":"function isValidToolName(name: string): boolean {\n  return name.length <= 64 && /^[a-zA-Z0-9_-]+$/.test(name.replace(/[^a-zA-Z0-9_-]/g, \"_\").slice(0, 64))\n}","tryCatchPattern":"try {\n  const tool = sanitiseToolName(rawName)\n} catch (e) {\n  if (e.message.includes(\"under 64 characters\")) {\n    const tool = sanitiseToolName(truncateWithHash(rawName, 64))\n  } else throw e\n}","preventionTips":["Keep table/query/datasource names short, especially with prefixes","Centralize tool-name derivation in one utility with length handling","Validate resource names at creation time against the 64-char limit"],"tags":["ai","tools","validation","naming"],"backgroundTag":"tool-name-length-exceeded","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}