gastownhall/beads · error
identifier too long: %q (max %d chars)
Error message
identifier too long: %q (max %d chars)
What it means
ValidateIdentifier rejects identifiers longer than 64 characters, matching the MySQL/Dolt identifier length limit, before they are used in DDL statements. This error means the supplied database or table name exceeds that limit and would be rejected (or truncated) by the server. It is surfaced to callers via QuoteIdentifier and wrappers like db: CreateDatabaseIfNotExists.
Source
Thrown at internal/storage/domain/db/ddl.go:17
package db
import (
"context"
"fmt"
"regexp"
)
var validIdentifier = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`)
const maxIdentifierLength = 64
// ValidateIdentifier checks whether name is safe to use, unquoted, as a
// database or table identifier in this package's DDL statements.
func ValidateIdentifier(name string) error {
if len(name) > maxIdentifierLength {
return fmt.Errorf("identifier too long: %q (max %d chars)", name, maxIdentifierLength)
}
if !validIdentifier.MatchString(name) {
return fmt.Errorf("invalid identifier: %q", name)
}
return nil
}
type DDLSQLRepository interface {
CreateDatabaseIfNotExists(ctx context.Context, database string) error
// CreateDatabase issues a bare CREATE DATABASE (no IF NOT EXISTS) so the
// server arbitrates creation atomically: success proves this call created
// the database; an already-exists error (MySQL 1007) proves it did not.
// The error is returned unmapped (wrapped with %w) so callers can
// classify it against their driver.
CreateDatabase(ctx context.Context, database string) error
UseDatabase(ctx context.Context, database string) error
}
View on GitHub (pinned to 71377f2769)
Solutions
- Shorten the database name to 64 characters or fewer before calling the DDL API.
- Derive names from shorter, stable inputs (project key or short hash) instead of full IDs/URLs.
- Pre-check names with db.ValidateIdentifier(name) to fail fast with a clear message.
- Fix the configuration/environment variable supplying the over-long name.
Example fix
// before
err := ddl.CreateDatabaseIfNotExists(ctx, "beads-"+longTenantUUID+"-production-us-east")
// after
name := "beads-" + shortHash(longTenantUUID) // <= 64 chars
if err := db.ValidateIdentifier(name); err != nil { return err }
err := ddl.CreateDatabaseIfNotExists(ctx, name) Defensive patterns
Strategy: validation
Validate before calling
func checkDBName(name string) error {
if len(name) > 64 {
return fmt.Errorf("database name %q exceeds 64 chars (len=%d)", name, len(name))
}
return db.ValidateIdentifier(name)
} Type guard
func validName(name string) bool {
return len(name) <= 64 && regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`).MatchString(name)
} Try / catch
if err := db.ValidateIdentifier(name); err != nil {
return fmt.Errorf("refusing DDL with bad name: %w", err)
}
err := ddl.CreateDatabaseIfNotExists(ctx, name) Prevention
- Cap derived database names at 64 characters using short hashes of long inputs.
- Run ValidateIdentifier on every name sourced from config or environment before DDL calls.
- Never concatenate raw user/tenant IDs into database names.
When it happens
Trigger: Calling CreateDatabaseIfNotExists, CreateDatabase, or UseDatabase with a database name whose length exceeds 64 characters (byte length of the string), or any code path that calls QuoteIdentifier/ValidateIdentifier with an over-long name.
Common situations: Programmatically derived database names (tenant IDs, hashed tokens, long project slugs) concatenated into names exceeding 64 chars; misconfigured BD_ or env-derived database names.
Related errors
- could not extract a Notion ID from %q
- invalid identifier: %q
- db: CreateDatabaseIfNotExists: %w
- no store is open for this workspace
- not found
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/db05545b11ff4bd2.
Report an issue: GitHub.