gastownhall/beads · error

ExternalDoltConfig: Host requires Port

Error message

ExternalDoltConfig: Host requires Port

What it means

A dependency's optional ThreadID is length-checked with types.CheckFieldLen("dependency thread_id", ...); over-length values are rejected with the dependency's index in the message and wrapped as ErrValidation.

Solutions

  1. Shorten the ThreadID to the allowed length.
  2. Move auxiliary data into Metadata (valid JSON) instead of overloading ThreadID.
  3. Pre-check with types.CheckFieldLen("dependency thread_id", id) client-side.

Example fix

// before
ThreadID: "sess-2026-08-30T10:00:00Z-very-long-worker-uuid-0f3a9c..." // too long
// after
ThreadID: "sess-0f3a9c"
Defensive patterns

Strategy: validation

Validate before calling

for i, d := range req.Dependencies {
    if err := types.CheckFieldLen("dependency thread_id", d.ThreadID); err != nil {
        return fmt.Errorf("dependency %d: %w", i, err)
    }
}

Try / catch

if err := store.ExecuteCreate(ctx, req); err != nil {
    if errors.Is(err, storage.ErrValidation) && errors.Is(err, types.ErrFieldTooLong) { /* shorten ThreadID */ }
    return err
}

Prevention

When it happens

Trigger: ExecuteCreate/ValidatePublicCreateRequest where request.Dependencies[index].ThreadID exceeds the allowed field length; check at public_create.go:174.

Common situations: Storing long session/thread identifiers, concatenating thread metadata into the ID field, or a schema/config change that reduced the max length after existing data was written.

Related errors


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

Appendix: source

Thrown at internal/configfile/external_dolt_config.go:50

func (c ExternalDoltConfig) ResolvedUser() string {
	if c.User == "" {
		return ExternalDoltConfigDefaultUser
	}
	return c.User
}

func (c ExternalDoltConfig) Validate() error {
	hasHost := c.Host != ""
	hasPort := c.Port != 0
	hasSocket := c.Socket != ""

	switch {
	case hasSocket && (hasHost || hasPort):
		return errors.New("ExternalDoltConfig: set either Socket OR (Host, Port), not both")
	case !hasSocket && !hasHost && !hasPort:
		return errors.New("ExternalDoltConfig: must set Socket or (Host, Port)")
	case hasHost && !hasPort:
		return errors.New("ExternalDoltConfig: Host requires Port")
	case !hasHost && hasPort:
		return errors.New("ExternalDoltConfig: Port requires Host")
	}

	if hasHost && (c.Port < 1 || c.Port > 65535) {
		return fmt.Errorf("ExternalDoltConfig: Port %d out of range [1, 65535]", c.Port)
	}

	if hasSocket && !filepath.IsAbs(c.Socket) {
		return fmt.Errorf("ExternalDoltConfig: Socket %q is not absolute", c.Socket)
	}

	switch {
	case c.TLSCert != "" && c.TLSKey == "":
		return errors.New("ExternalDoltConfig: TLSCert set without TLSKey")
	case c.TLSCert == "" && c.TLSKey != "":
		return errors.New("ExternalDoltConfig: TLSKey set without TLSCert")
	}

View on GitHub (pinned to 71377f2769)