gastownhall/beads · error

ExternalDoltConfig: Port requires Host

Error message

ExternalDoltConfig: Port requires Host

What it means

The waits-for specification's SpawnerID is length-checked via types.CheckFieldLen("waits-for spawner ID", ...) and any over-length value is rejected wrapped as ErrValidation. Unlike other field-length failures, the message is just "create: %w" with no index because at most one WaitsFor is allowed per create.

Source

Thrown at internal/configfile/external_dolt_config.go:52

		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")
	}

	if c.TLSCert != "" && !filepath.IsAbs(c.TLSCert) {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Shorten the SpawnerID to the allowed length and use the canonical issue ID.
  2. Pre-check with types.CheckFieldLen("waits-for spawner ID", id) before building the request.
  3. Verify the spawner issue exists too — length passes here but existence is checked at write time.

Example fix

// before
WaitsFor: &publicops.WaitsForInput{SpawnerID: "mol-molecule-run-2026-08-30-long-identifier"} // too long
// after
WaitsFor: &publicops.WaitsForInput{SpawnerID: "mol-123"}
Defensive patterns

Strategy: validation

Validate before calling

if req.WaitsFor != nil {
    if err := types.CheckFieldLen("waits-for spawner ID", req.WaitsFor.SpawnerID); err != nil { return err }
}

Try / catch

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

Prevention

When it happens

Trigger: ExecuteCreate/ValidatePublicCreateRequest with request.WaitsFor != nil and WaitsFor.SpawnerID exceeding the allowed ID length; check at public_create.go:184.

Common situations: Passing a long external ref or URL as the spawner ID; duplicated prefix in a hand-built ID.

Related errors


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