gastownhall/beads · error

ErrKindMismatch

ErrKindMismatch

Error message

pidfile: kind mismatch

What it means

ErrKindMismatch means the pidfile's kind field does not match the expected kind of the component doing the validation, e.g. a 'dolt-backend' pidfile found where a 'db-proxy' pidfile is required. This prevents a backend process record from being mistaken for a proxy and vice versa.

Source

Thrown at internal/storage/dbproxy/pidfile/pidfile.go:35

	Schema      int    `json:"schema,omitempty"`
	Kind        string `json:"kind,omitempty"`
	Birth       string `json:"birth,omitempty"`
	RootID      string `json:"root_id,omitempty"`
	ControlPort int    `json:"control_port,omitempty"`
}

const SchemaV2 = 2

const (
	KindProxy       = "db-proxy"
	KindDoltBackend = "dolt-backend"
)

var (
	ErrLegacySchema = errors.New("pidfile: legacy schema")
	ErrBadPid       = errors.New("pidfile: invalid pid")
	ErrBadPort      = errors.New("pidfile: invalid port")
	ErrKindMismatch = errors.New("pidfile: kind mismatch")
	ErrMissingBirth = errors.New("pidfile: missing birth token")
)

// ValidateV2 validates the fields required for a schema v2 pidfile.
func (p *PidFile) ValidateV2(wantKind string) error {
	if p.Schema < SchemaV2 {
		return ErrLegacySchema
	}
	if p.Pid <= 0 {
		return ErrBadPid
	}
	if p.Port < 1 || p.Port > 65535 || (p.ControlPort != 0 && (p.ControlPort < 1 || p.ControlPort > 65535)) {
		return ErrBadPort
	}
	if p.Kind != wantKind {
		return ErrKindMismatch
	}
	if p.Birth == "" {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Point the caller at the correct pidfile path for the component kind
  2. Delete the mismatched stale pidfile and restart the component
  3. Check errors.Is(err, pidfile.ErrKindMismatch) and skip (not kill) the foreign record

Example fix

// before
if err := pf.ValidateV2(pidfile.KindProxy); err != nil { return err }
// after
if err := pf.ValidateV2(pidfile.KindProxy); err != nil {
    if errors.Is(err, pidfile.ErrKindMismatch) {
        return nil // foreign pidfile: leave it alone
    }
    return err
}
Defensive patterns

Strategy: type-guard

Validate before calling

var pf pidfile.PidFile
json.Unmarshal(data, &pf)
if pf.Kind != pidfile.KindProxy { return fmt.Errorf("expected %s pidfile, got %s", pidfile.KindProxy, pf.Kind) }

Type guard

func isKindMismatch(err error) bool { return errors.Is(err, pidfile.ErrKindMismatch) }

Try / catch

if err := pf.ValidateV2(wantKind); err != nil {
    if errors.Is(err, pidfile.ErrKindMismatch) { return nil /* skip foreign record */ }
    return err
}

Prevention

When it happens

Trigger: ValidateV2(wantKind) called with a wantKind (KindProxy or KindDoltBackend) that differs from the pidfile's recorded Kind; readAndDial/stopAndAcquire probing a pidfile belonging to another component.

Common situations: Configuration pointing a proxy client at a backend pidfile path; two components sharing a workspace directory; leftover pidfile from a differently-configured run.

Related errors


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