{"record":{"id":"a84aee8c9c01b8b7","repo":"gastownhall/beads","slug":"peer-name-cannot-be-empty","errorCode":null,"errorMessage":"peer name cannot be empty","messagePattern":"peer name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/credentials.go","lineNumber":42,"sourceCode":"// Credential storage and encryption for federation peers.\n// Enables SQL user authentication when syncing with peer workspaces.\n\n// credentialKeyFile is the filename for the random encryption key stored alongside the database.\nconst credentialKeyFile = \".beads-credential-key\" //nolint:gosec // G101: not a credential, just a filename\n\nconst awsResponseChecksumValidationEnv = \"AWS_RESPONSE_CHECKSUM_VALIDATION\"\n\n// federationEnvMutex protects process-wide env vars from concurrent access.\n// Environment variables are process-global, so we need to serialize federation operations.\nvar federationEnvMutex sync.Mutex\n\n// validPeerNameRegex matches valid peer names (alphanumeric, hyphens, underscores)\nvar validPeerNameRegex = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_-]*$`)\n\n// validatePeerName checks that a peer name is safe for use as a Dolt remote name\nfunc validatePeerName(name string) error {\n\tif name == \"\" {\n\t\treturn fmt.Errorf(\"peer name cannot be empty\")\n\t}\n\tif len(name) > 64 {\n\t\treturn fmt.Errorf(\"peer name too long (max 64 characters)\")\n\t}\n\tif !validPeerNameRegex.MatchString(name) {\n\t\treturn fmt.Errorf(\"peer name must start with a letter and contain only alphanumeric characters, hyphens, and underscores\")\n\t}\n\treturn nil\n}\n\n// initCredentialKey loads or generates the credential encryption key.\n// The key file is stored in .beads/ (beadsDir), NOT in .beads/dolt/ (dbPath),\n// to avoid creating ghost directories in shared-server mode (GH bd-cby).\n// Falls back to the old dbPath location for transparent migration.\nfunc (s *DoltStore) initCredentialKey(ctx context.Context) error {\n\tif s.beadsDir == \"\" {\n\t\treturn nil // No filesystem path — credential encryption unavailable\n\t}","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/credentials.go#L24-L60","documentation":"validatePeerName rejects an empty peer name when adding a federation peer credential. Peer names become Dolt remote names, so they must be non-empty, start with a letter, and contain only alphanumerics, hyphens, and underscores (max 64 chars). This is the empty-name branch.","triggerScenarios":"addFederationPeer is called (or a `bd` federation/peer add command run) with an empty string as the peer name — e.g. a missing CLI argument, an unset config field, or an empty env var interpolated into the peer name.","commonSituations":"Forgot to pass the peer name argument on the CLI; YAML/JSON config with `name: \"\"`; scripting with an unset variable (`bd peer add $PEER` with PEER empty).","solutions":["Supply a non-empty peer name, e.g. `bd peer add alice` / set `name: \"alice\"` in config","Check the shell variable or config key actually has a value before invoking (`echo \"$PEER\"`)","Use a name starting with a letter, e.g. `peer-1` or `backup_remote`"],"exampleFix":"// before\nPEER=\"\"; bd peer add \"$PEER\"   # peer name cannot be empty\n// after\nPEER=\"backup-remote\"; bd peer add \"$PEER\"","handlingStrategy":"validation","validationCode":"// same rules as validatePeerName\nvar peerNameRe = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_-]*$`)\nfunc validPeerName(name string) bool {\n    return name != \"\" && len(name) <= 64 && peerNameRe.MatchString(name)\n}","typeGuard":"func validPeerName(name string) bool {\n    return name != \"\" && len(name) <= 64 &&\n        regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_-]*$`).MatchString(name)\n}","tryCatchPattern":null,"preventionTips":["Always pass an explicit, non-empty peer name to federation/peer add commands","Validate shell/config variables are non-empty before interpolation","Fail fast in scripts: `[ -n \"$PEER\" ] || exit 1`","Keep names short and letter-initial by convention"],"tags":["validation","federation","peer-name","config"],"backgroundTag":"invalid-peer-name","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}