gastownhall/beads · error
ExternalDoltConfig: TLSCACert set without TLSRequired
Error message
ExternalDoltConfig: TLSCACert set without TLSRequired
What it means
The same source->target edge may not appear twice with the same dependency type. validatePublicCreateDependencies deduplicates edges (including the implicit parent edge and waits-for edge) and refuses exact duplicates with this message naming both endpoint IDs, wrapped as ErrValidation. (Same pair with a different type produces a DependencyTypeConflictError instead.)
Source
Thrown at internal/configfile/external_dolt_config.go:83
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) {
return fmt.Errorf("ExternalDoltConfig: TLSCert %q is not absolute", c.TLSCert)
}
if c.TLSKey != "" && !filepath.IsAbs(c.TLSKey) {
return fmt.Errorf("ExternalDoltConfig: TLSKey %q is not absolute", c.TLSKey)
}
if c.TLSCACert != "" && !filepath.IsAbs(c.TLSCACert) {
return fmt.Errorf("ExternalDoltConfig: TLSCACert %q is not absolute", c.TLSCACert)
}
if !c.TLSRequired {
switch {
case c.TLSCACert != "":
return errors.New("ExternalDoltConfig: TLSCACert set without TLSRequired")
case c.TLSCert != "" || c.TLSKey != "":
return errors.New("ExternalDoltConfig: TLSCert/TLSKey set without TLSRequired")
case c.TLSServerName != "":
return errors.New("ExternalDoltConfig: TLSServerName set without TLSRequired")
case c.TLSSkipVerify:
return errors.New("ExternalDoltConfig: TLSSkipVerify set without TLSRequired")
}
}
if c.TLSRequired && hasSocket && c.TLSServerName == "" && !c.TLSSkipVerify {
return errors.New("ExternalDoltConfig: TLSRequired over Socket needs TLSServerName or TLSSkipVerify")
}
if c.KeepAlivePeriod < 0 {
return fmt.Errorf("ExternalDoltConfig: KeepAlivePeriod %s is negative", c.KeepAlivePeriod)
}
return nilView on GitHub (pinned to 71377f2769)
Solutions
- Deduplicate request.Dependencies by (TargetID, Type) before submitting.
- Remove the entry duplicating the implicit ParentID edge.
- Use a set keyed by source:target:type when building dependencies programmatically.
Example fix
// before
req.Dependencies = []publicops.DependencyInput{{TargetID: "bd-2", Type: types.DepBlocks}, {TargetID: "bd-2", Type: types.DepBlocks}}
// after
req.Dependencies = dedupeDeps(req.Dependencies) // keep one {bd-2, blocks} entry Defensive patterns
Strategy: validation
Validate before calling
seen := map[string]bool{}
for _, d := range req.Dependencies {
k := d.TargetID + ":" + string(d.Type)
if seen[k] { return fmt.Errorf("duplicate dependency %s", d.TargetID) }
seen[k] = true
} Try / catch
if err := store.ExecuteCreate(ctx, req); err != nil {
if errors.Is(err, storage.ErrValidation) && strings.Contains(err.Error(), "duplicate dependency") { /* dedupe and retry submit */ }
return err
} Prevention
- Deduplicate by (TargetID, Type) before building the request.
- Remember the implicit ParentID edge counts toward duplicates.
- Use a set when aggregating dependencies from multiple sources.
When it happens
Trigger: ExecuteCreate/ValidatePublicCreateRequest where two Dependencies entries produce an identical (source,target,type) edge — e.g. the same TargetID+Type listed twice, or a dependency duplicating the implicit ParentID edge; check at public_create.go:203.
Common situations: Merging dependency lists from two sources without deduplication; retry logic re-appending dependencies; Reverse flag and normal direction accidentally producing the same pair; batch templates that already embed the parent edge.
Related errors
- no store is open for this workspace
- no absolute native user directory is available
- ExternalDoltConfig: set either Socket OR (Host, Port), not b
- ExternalDoltConfig: must set Socket or (Host, Port)
- ExternalDoltConfig: Host requires Port
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a1d6a7f17daa0620.
Report an issue: GitHub.