gastownhall/beads · error

unsafe dolt status table name %q

Error message

unsafe dolt status table name %q

What it means

dirtyTableSignature interpolates a table name from dolt_status into a dolt_diff('HEAD','WORKING', '<table>') literal, so it first validates the name against doltStatusTableNameRE to prevent SQL injection through a crafted table name. A name that does not match the safe pattern yields "unsafe dolt status table name %q" and the diff is never executed.

Source

Thrown at internal/storage/schema/schema.go:862

	for table := range tables {
		names = append(names, table)
	}
	sort.Strings(names)
	return names
}

func sortedSignatureTableNames(signatures map[string]string) []string {
	names := make([]string, 0, len(signatures))
	for table := range signatures {
		names = append(names, table)
	}
	sort.Strings(names)
	return names
}

func dirtyTableSignature(ctx context.Context, db DBConn, table string) (string, error) {
	if !doltStatusTableNameRE.MatchString(table) {
		return "", fmt.Errorf("unsafe dolt status table name %q", table)
	}
	//nolint:gosec // table comes from dolt_status; dolt_diff requires a literal table argument.
	rows, err := db.QueryContext(ctx, "SELECT * FROM dolt_diff('HEAD', 'WORKING', "+sqlStringLiteral(table)+")")
	if err != nil {
		return "", err
	}
	defer rows.Close()

	columns, err := rows.Columns()
	if err != nil {
		return "", err
	}

	var rowSignatures []string
	for rows.Next() {
		values := make([]any, len(columns))
		dest := make([]any, len(columns))
		for i := range values {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Find the offending table with `dolt status` in the .beads database directory — the message quotes the exact rejected name.
  2. Rename the table to a plain identifier (letters, digits, underscores): `dolt sql -q "RENAME TABLE \`bad name\` TO good_name"`, then retry `bd`.
  3. If the table is junk created by tooling, drop it: `dolt sql -q "DROP TABLE \`bad name\`"`.
  4. If dolt_status itself contains entries for nonexistent tables, verify against `dolt status` output and repair the working set (dolt reset --hard only if data loss is acceptable).
  5. If a legitimately simple table name is rejected, check your beads/Dolt version — a regex/version mismatch should be reported upstream.

Example fix

// before: a table named `we;ird'name` in dolt_status poisons the signature pass
err := schema.MigrateUp(ctx, db) // unsafe dolt status table name "we;ird'name"
// after: rename to a safe identifier via dolt, then migrate
//   dolt sql -q "RENAME TABLE `we;ird'name` TO weird_name"
err = schema.MigrateUp(ctx, db)
Defensive patterns

Strategy: validation

Validate before calling

// Go: mirror the library's allowlist before creating tables in the beads DB
var safeTableRE = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`)
func safeTableName(name string) bool { return safeTableRE.MatchString(name) }

Type guard

// Go: extract the rejected name from the error message
func unsafeTableName(err error) (string, bool) {
    const prefix = "unsafe dolt status table name "
    if err == nil || !strings.Contains(err.Error(), prefix) {
        return "", false
    }
    msg := err.Error()
    i := strings.Index(msg, prefix)
    rest := msg[i+len(prefix):]
    if len(rest) >= 2 {
        return strings.Trim(rest, "\""), true
    }
    return "", false
}

Try / catch

err := schema.MigrateUp(ctx, db)
if err != nil {
    if name, ok := unsafeTableName(err); ok {
        // rename/drop `name` via dolt, then retry
        return fmt.Errorf("fix table %q (rename to [A-Za-z0-9_]) and retry", name)
    }
    return err
}

Prevention

When it happens

Trigger: Any code path fingerprinting dirty tables (dirtyTableSignatures / changedDirtyTableSignatures during MigrateUp) encounters a table name in dolt_status that fails the safe-name regex — e.g. names with quotes, semicolons, backslashes, or other characters outside the allowlist pattern.

Common situations: A table created by hand or by another tool with exotic characters in its name inside the .beads Dolt database; a corrupted or tampered dolt_status; a Dolt version producing status entries with quoted/backticked name formatting that beads' regex does not accept.

Related errors


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