gastownhall/beads · error

dolt: credential from %s contains a character (:, @, or /) t

Error message

dolt: credential from %s contains a character (:, @, or /) that cannot be placed in the connection username

What it means

Fail-closed validation in ApplyGatewayCredential: the credential value becomes the DSN username, and the go-sql-driver DSN grammar has no escaping for the user field, so any ':', '@', or '/' would silently split the token into wrong user/password parts. JWTs (base64url + '.') are safe; anything containing those three characters is rejected.

Source

Thrown at internal/storage/dolt/gateway_credential.go:54

		Kind:    creds.KindIdentity,
		Label:   "BEADS_DOLT_CREDENTIAL_COMMAND",
	})
	if err != nil {
		return false, err
	}
	if !ok {
		return false, nil
	}
	// Defense in depth: the token is presented AS the username, so a non-identity
	// credential must never reach this slot.
	if cred.Kind != creds.KindIdentity {
		return false, fmt.Errorf("dolt: credential from %s is not an identity; refusing to present it as the connection username", cred.Source)
	}
	// The token becomes the DSN username; the go-sql-driver grammar has no escaping for
	// the user field, so a ':' '@' or '/' would silently mis-split it into user/password.
	// Reject rather than connect with a mangled identity. (JWTs are base64url + '.', safe.)
	if strings.ContainsAny(cred.Value, ":@/") {
		return false, fmt.Errorf("dolt: credential from %s contains a character (:, @, or /) that cannot be placed in the connection username", cred.Source)
	}
	// cred.Username (a dynamic user/password pair) is meaningless here: the token IS the
	// username. Ignored deliberately.
	cfg.ServerUser = cred.Value
	cfg.Gateway = true
	cfg.DisableAutoStart = true
	return true, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Replace the credential value with the raw token (JWTs are safe: base64url + '.') without scheme or user:pass decoration
  2. Check the credential source (cred.Source) for where the malformed value is stored and correct it
  3. Sanitize/validate tokens at the point of credential creation to reject ':@/' early
  4. Re-run ApplyGatewayCredential after fixing the stored value

Example fix

// before
cred.Value = "https://user:token@example.com" // contains ':', '@', '/' -> rejected
// after
cred.Value = "eyJhbGciOi..." // raw JWT, safe for the DSN username slot
Defensive patterns

Strategy: validation

Validate before calling

func tokenSafeForDSN(v string) error {
	if v == "" { return errors.New("empty credential value") }
	if strings.ContainsAny(v, ":@/") { return fmt.Errorf("token %q unusable as DSN username", v) }
	return nil
}
if err := tokenSafeForDSN(cred.Value); err != nil { return err }

Type guard

func isDSNSafeToken(v string) bool {
	return v != "" && !strings.ContainsAny(v, ":@/")
}

Try / catch

ok, err := ApplyGatewayCredential(cfg, cred)
if err != nil && strings.Contains(err.Error(), "cannot be placed in the connection username") {
	// rotate/re-store the credential as a raw JWT
}

Prevention

When it happens

Trigger: The resolved gateway credential's Value contains ':', '@', or '/' — e.g. a basic-auth style 'user:pass' string, a URL containing '/', or a token with embedded '@' — and is about to be set as cfg.ServerUser.

Common situations: Operator storing a full DSN or basic-auth string as the gateway credential instead of the raw bearer token; copy-paste including scheme 'https://' in the token; legacy credential values predating the JWT-only format.

Related errors


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