{"record":{"id":"978dc9dc6fc99010","repo":"gastownhall/beads","slug":"table-name-too-long","errorCode":null,"errorMessage":"table name too long","messagePattern":"table name too long","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/history.go","lineNumber":48,"sourceCode":"\tif name == \"\" {\n\t\treturn fmt.Errorf(\"database name cannot be empty\")\n\t}\n\tif len(name) > 64 {\n\t\treturn fmt.Errorf(\"database name too long\")\n\t}\n\tif !validDatabasePattern.MatchString(name) {\n\t\treturn fmt.Errorf(\"invalid database name: %s\", name)\n\t}\n\treturn nil\n}\n\n// validateTableName checks if a table name is safe to use in queries\nfunc validateTableName(table string) error {\n\tif table == \"\" {\n\t\treturn fmt.Errorf(\"table name cannot be empty\")\n\t}\n\tif len(table) > 64 {\n\t\treturn fmt.Errorf(\"table name too long\")\n\t}\n\tif !validTablePattern.MatchString(table) {\n\t\treturn fmt.Errorf(\"invalid table name: %s\", table)\n\t}\n\treturn nil\n}\n\n// issueHistory represents an issue at a specific point in history\ntype issueHistory struct {\n\tIssue      *types.Issue\n\tCommitHash string\n\tCommitter  string\n\tCommitDate time.Time\n}\n\n// getIssueHistory returns the complete history of an issue\nfunc (s *DoltStore) getIssueHistory(ctx context.Context, issueID string) ([]*issueHistory, error) {\n\t// Wrap in a subquery to avoid Dolt's max1Row optimization on PK lookup.","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/history.go#L30-L66","documentation":"validateTableName enforces the same 64-character identifier limit as database names, matching MySQL/Dolt identifier limits. Table names are interpolated into backtick-quoted SQL, and the server would reject anything longer, so the library fails fast with a clear message.","triggerScenarios":"Passing a table name longer than 64 bytes into any internal query path that validates via validateTableName (e.g. history queries against dolt_history_<table> or conflict queries).","commonSituations":"Programmatically generated table names combining long prefixes and suffixes (e.g. 'dolt_history_' + a long name exceeding 64 bytes); tenant-prefixed table schemes; name collisions with schema-migration limits.","solutions":["Shorten the table name to 64 bytes or fewer before querying.","If deriving history/table names dynamically, truncate the base identifier so the composed name (including any 'dolt_history_' prefix budget) stays within 64 bytes.","Review code that concatenates prefixes/suffixes onto table names and add a length check at the composition point."],"exampleFix":"// before\ntable := \"issues_\" + strings.Repeat(\"x\", 80)\nvalidateTableName(table) // fails\n// after\ntable := \"issues_\" + hash[:12] // keep total length <= 64\nvalidateTableName(table)","handlingStrategy":"validation","validationCode":"func validTableName(t string) bool { return len(t) > 0 && len(t) <= 64 }\nif !validTableName(table) { return fmt.Errorf(\"table name %q must be 1-64 chars\", table) }","typeGuard":"func isShortIdentifier(s string) bool { return len(s) <= 64 }","tryCatchPattern":null,"preventionTips":["When composing table names from prefixes/suffixes, check the total length at the composition point.","Budget for system prefixes like 'dolt_history_' when sizing base names.","Prefer hashing long components to fixed-length fragments."],"tags":["validation","table-name","identifier-length","dolt"],"backgroundTag":"database-name-too-long","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}