{"record":{"id":"58f36c5b6f693734","repo":"gastownhall/beads","slug":"external-reference-must-start-with-external","errorCode":null,"errorMessage":"external reference must start with 'external:'","messagePattern":"external reference must start with 'external:'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/dep.go","lineNumber":1490,"sourceCode":"\t}\n\n\t// Add READY/BLOCKED indicator for root node\n\tif node.Status == types.StatusOpen && node.Depth == 0 {\n\t\tif isBlocked {\n\t\t\tline += \" \" + ui.FailStyle.Bold(true).Render(\"[BLOCKED]\")\n\t\t} else {\n\t\t\tline += \" \" + ui.PassStyle.Bold(true).Render(\"[READY]\")\n\t\t}\n\t}\n\n\treturn line\n}\n\n// validateExternalRef validates the format of an external dependency reference.\n// Valid format: external:<project>:<capability>\nfunc validateExternalRef(ref string) error {\n\tif !strings.HasPrefix(ref, \"external:\") {\n\t\treturn fmt.Errorf(\"external reference must start with 'external:'\")\n\t}\n\n\tparts := strings.SplitN(ref, \":\", 3)\n\tif len(parts) != 3 {\n\t\treturn fmt.Errorf(\"invalid external reference format: expected 'external:<project>:<capability>', got '%s'\", ref)\n\t}\n\n\tproject := parts[1]\n\tcapability := parts[2]\n\n\tif project == \"\" {\n\t\treturn fmt.Errorf(\"external reference missing project name\")\n\t}\n\tif capability == \"\" {\n\t\treturn fmt.Errorf(\"external reference missing capability name\")\n\t}\n\n\treturn nil","sourceCodeStart":1472,"sourceCodeEnd":1508,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/dep.go#L1472-L1508","documentation":"validateExternalRef rejects any external dependency reference that does not begin with the literal prefix 'external:'. External refs point at dependencies outside the local beads database and must follow 'external:<project>:<capability>'. Thrown early so malformed refs never reach storage.","triggerScenarios":"Calling `bd dep add <id> <ref>` (or an external-dep API that routes through validateExternalRef) where ref lacks the 'external:' prefix, e.g. passing 'github.com:api' or a plain issue ID where an external ref is expected.","commonSituations":"Forgetting the prefix when scripting cross-project links; confusing external refs with regular issue IDs; older scripts written before the 'external:' convention existed.","solutions":["Prefix the reference with 'external:': e.g. external:myproject:deploy-api.","Use the full three-part form external:<project>:<capability> — the prefix alone is not enough.","If you meant a local issue, use its plain ID (bd-123) with the normal dep type, not the external path."],"exampleFix":"// before\nbd dep add bd-1 external myproject:deploy\n\n// after\nbd dep add bd-1 external:myproject:deploy","handlingStrategy":"validation","validationCode":"func isValidExternalRefPrefix(ref string) bool { return strings.HasPrefix(ref, \"external:\") }\n// shell: case \"$ref\" in external:*) ;; *) echo \"ref must start with external:\" >&2; exit 1;; esac","typeGuard":null,"tryCatchPattern":"if err := validateExternalRef(ref); err != nil {\n\tif strings.Contains(err.Error(), \"must start with 'external:'\") {\n\t\tref = \"external:\" + strings.TrimPrefix(ref, \"external\")\n\t}\n\treturn err\n}","preventionTips":["Build external refs with a helper that always prepends 'external:'.","Never pass plain issue IDs where an external ref is expected.","Add a lint step in scripts that checks the prefix before bd dep add."],"tags":["validation","external-references","dependencies"],"backgroundTag":"invalid-reference-format","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}