gastownhall/beads · error
ExternalDoltConfig: set either Socket OR (Host, Port), not b
Error message
ExternalDoltConfig: set either Socket OR (Host, Port), not both
What it means
Each dependency entry must carry a non-empty TargetID and a valid DependencyType; validatePublicCreateDependencies refuses entries missing either with this fixed message. Unlike other checks it does not include the index, so scan request.Dependencies for the offending entry.
Source
Thrown at internal/configfile/external_dolt_config.go:46
TLSSkipVerify bool `json:"tls_skip_verify,omitempty"`
KeepAlivePeriod time.Duration `json:"keep_alive_period,omitempty"`
}
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 == "":View on GitHub (pinned to 71377f2769)
Solutions
- Set both TargetID and a valid Type (e.g. types.DepBlocks, DepRelated, DepParentChild, DepWaitsFor) on every dependency entry.
- Check the JSON/struct field name mapping so Type is actually populated.
- Validate entries in a loop before calling ExecuteCreate, mirroring dependency.Type.IsValid().
Example fix
// before
req.Dependencies = append(req.Dependencies, publicops.DependencyInput{TargetID: "bd-2"}) // Type unset
// after
req.Dependencies = append(req.Dependencies, publicops.DependencyInput{TargetID: "bd-2", Type: types.DepBlocks}) Defensive patterns
Strategy: validation
Validate before calling
for _, d := range req.Dependencies {
if d.TargetID == "" || !d.Type.IsValid() { return errors.New("dependency target and type are required") }
} Type guard
func depValid(d publicops.DependencyInput) bool { return d.TargetID != "" && d.Type.IsValid() } Try / catch
if err := store.ExecuteCreate(ctx, req); err != nil {
if errors.Is(err, storage.ErrValidation) && strings.Contains(err.Error(), "target and type are required") { /* fix inputs */ }
return err
} Prevention
- Always set Type explicitly on DependencyInput — never rely on zero values.
- Check struct tag/JSON field names when deserializing dependencies.
- Only use types.DependencyType constants, not raw strings.
When it happens
Trigger: ExecuteCreate/ValidatePublicCreateRequest where a Dependencies element has TargetID == "" or dependency.Type not matching a known types.DependencyType (Type.IsValid() false); check at public_create.go:168.
Common situations: Constructing DependencyInput structs programmatically and forgetting to set Type; deserializing JSON where the type field is named differently and lands as zero value; using a custom/renamed dependency type string not in the valid set.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- no store is open for this workspace
- no absolute native user directory is available
- ExternalDoltConfig: must set Socket or (Host, Port)
- ExternalDoltConfig: Host requires Port
- ExternalDoltConfig: TLSKey set without TLSCert
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0fd6ad7e38f9cc90.
Report an issue: GitHub.