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

  1. Shorten the database name to 64 characters or fewer before calling the DDL API.
  2. Derive names from shorter, stable inputs (project key or short hash) instead of full IDs/URLs.
  3. Pre-check names with db.ValidateIdentifier(name) to fail fast with a clear message.
  4. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/db05545b11ff4bd2. Report an issue: GitHub.