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.
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)
Solutions
- Shorten the ThreadID to the allowed length.
- Move auxiliary data into Metadata (valid JSON) instead of overloading ThreadID.
- 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
- Keep thread identifiers short and hash long values.
- Move extra data into Metadata JSON.
- Pre-check lengths with types.CheckFieldLen.
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
- no absolute native user directory is available
- no store is open for this workspace
- ExternalDoltConfig: set either Socket OR (Host, Port), not b
- ExternalDoltConfig: must set Socket or (Host, Port)
- ExternalDoltConfig: Port requires Host
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/ec72b0ae14dfea4e.
Report an issue: GitHub.