gastownhall/beads · error
invalid external reference format: expected 'external:<proje
Error message
invalid external reference format: expected 'external:<project>:<capability>', got '%s'
What it means
After confirming the 'external:' prefix, validateExternalRef splits the remainder on ':' and requires exactly three parts. If the ref does not match external:<project>:<capability>, this error reports the expected format and echoes the offending value.
Source
Thrown at cmd/bd/dep.go:1495
line += " " + ui.FailStyle.Bold(true).Render("[BLOCKED]")
} else {
line += " " + ui.PassStyle.Bold(true).Render("[READY]")
}
}
return line
}
// validateExternalRef validates the format of an external dependency reference.
// Valid format: external:<project>:<capability>
func validateExternalRef(ref string) error {
if !strings.HasPrefix(ref, "external:") {
return fmt.Errorf("external reference must start with 'external:'")
}
parts := strings.SplitN(ref, ":", 3)
if len(parts) != 3 {
return fmt.Errorf("invalid external reference format: expected 'external:<project>:<capability>', got '%s'", ref)
}
project := parts[1]
capability := parts[2]
if project == "" {
return fmt.Errorf("external reference missing project name")
}
if capability == "" {
return fmt.Errorf("external reference missing capability name")
}
return nil
}
// IsExternalRef returns true if the dependency reference is an external reference.
func IsExternalRef(ref string) bool {
return strings.HasPrefix(ref, "external:")View on GitHub (pinned to 71377f2769)
Solutions
- Restructure the ref to exactly two segments after the prefix: external:<project>:<capability>.
- Replace ':' inside capability names with '-' or another separator, e.g. external:myproject:api-v2 instead of external:myproject:api:v2.
- Ensure the project and capability segments are both non-empty (see errors 345/346).
Example fix
// before
validateExternalRef("external:myproject") // only one segment
// after
validateExternalRef("external:myproject:deploy-api") Defensive patterns
Strategy: validation
Validate before calling
func isWellFormedExternalRef(ref string) bool {
parts := strings.SplitN(strings.TrimPrefix(ref, "external:"), ":", 3)
return len(parts) == 3 && parts[0] != "" && parts[1] != ""
} Type guard
func asExternalRef(ref string) (project, capability string, ok bool) {
if !strings.HasPrefix(ref, "external:") { return "", "", false }
parts := strings.SplitN(strings.TrimPrefix(ref, "external:"), ":", 3)
if len(parts) != 3 { return "", "", false }
return parts[0], parts[1], true
} Try / catch
if err := validateExternalRef(ref); err != nil {
if strings.HasPrefix(err.Error(), "invalid external reference format") {
fmt.Fprintf(os.Stderr, "fix ref %q to external:<project>:<capability>\n", ref)
}
return err
} Prevention
- Sanitize colons out of project/capability names before composing refs.
- Never embed URLs directly as external refs; extract project and capability first.
- Unit-test ref formatting helpers with malformed inputs.
When it happens
Trigger: Passing an external ref with the wrong number of colons to the external dependency path: 'external:onlyproject' (1 part), 'external:a:b:extra' (SplitN caps at 3 but a 4-segment ref still yields unexpected capability content — actually 4 segments split to 3 with capability 'b:extra', but a ref like 'external:a:b:c:d' intent mismatch), or 'external:' with empty remainder.
Common situations: Capability names containing colons; omitting the capability segment; copying a ref from docs and dropping a segment; embedding URLs (which contain '://') as the project/capability.
Related errors
- external reference must start with 'external:'
- external reference missing project name
- external reference missing capability name
- no store is open for this workspace
- no absolute native user directory is available
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/902dbabb70e867bc.
Report an issue: GitHub.