gastownhall/beads · error

ErrFieldTooLong

ErrFieldTooLong

Error message

field exceeds maximum length

What it means

ErrFieldTooLong is returned when a bounded text field (title, description, etc.) exceeds MaxFieldLen (255) characters, matching the backend VARCHAR(255) columns. CheckFieldLen produces it wrapped with the field name for context. Length is counted in runes, not bytes, so multibyte values up to 255 characters are fine. Callers should errors.Is it rather than matching raw backend 'data too long' strings.

Source

Thrown at internal/types/types.go:292

	w.h.Write([]byte(fmt.Sprintf("%d", d)))
	w.h.Write([]byte{0})
}

func (w hashFieldWriter) flag(b bool, label string) {
	if b {
		w.h.Write([]byte(label))
	}
	w.h.Write([]byte{0})
}

// MaxFieldLen is the maximum length (in characters) of common bounded text
// fields, matching their VARCHAR(255) columns.
const MaxFieldLen = 255

// ErrFieldTooLong is returned when a bounded text field exceeds MaxFieldLen
// characters. Callers can errors.Is it instead of matching a raw backend "data
// too long" string.
var ErrFieldTooLong = errors.New("field exceeds maximum length")

// CheckFieldLen returns ErrFieldTooLong (wrapped with context) when val exceeds
// MaxFieldLen characters. name is the field label used in the message. Length is
// counted in runes, not bytes, so a multibyte value up to MaxFieldLen characters
// fits the VARCHAR(255) column and passes.
func CheckFieldLen(name, val string) error {
	if n := utf8.RuneCountInString(val); n > MaxFieldLen {
		return fmt.Errorf("%w: %s is %d characters (max %d)", ErrFieldTooLong, name, n, MaxFieldLen)
	}
	return nil
}

// MaxTextBytes is the maximum size, in BYTES, of a `TEXT` column — the storage
// ceiling for the values this schema keeps in one rather than in a LONGTEXT.
//
// BYTES, NOT CHARACTERS, which is the one place this differs from MaxFieldLen
// beside it and the reason CheckTextLen does not simply call CheckFieldLen with
// a bigger number: MySQL and Dolt bound a TEXT column by its encoded length, so

View on GitHub (pinned to 71377f2769)

Solutions

  1. Truncate or shorten the offending field to 255 runes or fewer before calling the API.
  2. Move long content into the description field if it has a larger bound, keeping only a short summary in the title.
  3. Pre-validate with types.CheckFieldLen(name, val) and handle the wrapped error to surface which field was too long.
  4. Do not match raw backend 'data too long' errors; use errors.Is(err, types.ErrFieldTooLong) for classification.

Example fix

// before
issue.Title = strings.Join(longParts, " ")
bd.Create(issue) // fails: field exceeds maximum length

// after
title := strings.Join(longParts, " ")
if err := types.CheckFieldLen("title", title); err != nil {
    title = string([]rune(title)[:255])
}
issue.Title = title
Defensive patterns

Strategy: validation

Validate before calling

if err := types.CheckFieldLen("title", issue.Title); err != nil {
    return err // too long, fix before calling the API
}

Try / catch

if errors.Is(err, types.ErrFieldTooLong) {
    // truncate the named field and retry or report
}

Prevention

When it happens

Trigger: Calling CheckFieldLen (or any create/update path that validates fields) with a title, label, or other bounded string longer than 255 characters; e.g. bd create with an extremely long --title or programmatically passing oversized values to issue create/update.

Common situations: Pasting long log excerpts or generated text into the title field; importing issues from another tracker with unbounded field lengths; generating titles from commit messages or URLs that exceed 255 characters.

Related errors


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