{"record":{"id":"86a3ab6767699ab2","repo":"gastownhall/beads","slug":"proxied-server-provider-t-does-not-offer-the-add","errorCode":null,"errorMessage":"proxied-server provider %T does not offer the add-comment surface","messagePattern":"proxied-server provider %T does not offer the add-comment surface","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/comments_proxied_server.go","lineNumber":110,"sourceCode":"\n\tif jsonOutput {\n\t\treturn outputJSON(comment)\n\t}\n\tfmt.Printf(\"Comment added to %s\\n\", issue.ID)\n\treturn nil\n}\n\n// proxiedCommenter hands back the guarded add-comment surface for the\n// proxied-server provider, through the provider's OWN capability accessor —\n// the same two-step proxiedIssueReader performs, and for the same reason: the\n// accessor is where each layer is added.\nfunc proxiedCommenter() (issueops.Commenter, error) {\n\tif uowProvider == nil {\n\t\treturn nil, errors.New(\"proxied-server UOW provider not initialized\")\n\t}\n\tsrc, ok := uowProvider.(uow.CommenterSource)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"proxied-server provider %T does not offer the add-comment surface\", uowProvider)\n\t}\n\treturn src.Commenter()\n}\n\n// addCommentProxied appends one comment through the Commenter role and returns\n// it with the issue it landed on.\n//\n// The RESOLVE stays here, in a read-only pre-flight, for the reason the\n// proxied close keeps its own policy pre-flight: `bd comment` refuses a\n// template, and refusing a template is not library policy. The pre-flight is\n// also where the TITLE comes from — the confirmation line prints it, and a\n// result type carrying presentation for one front door is a result type that\n// grows one field per front door. The role is handed the canonical id the\n// pre-flight resolved, exactly as `bd show` hands Reader.Get one.\nfunc addCommentProxied(ctx context.Context, id, author, text string) (*types.Comment, *types.Issue, error) {\n\tissue, err := resolveCommentTargetProxied(ctx, id)\n\tif err != nil {\n\t\treturn nil, nil, err","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/comments_proxied_server.go#L92-L128","documentation":"Capability-mismatch guard for the add-comment path in proxied-server mode: the uowProvider does not implement `uow.CommenterSource`, so no Commenter role can be obtained. Mirrors the batch-close guard — it signals a wiring or version mismatch, not a user data problem.","triggerScenarios":"`bd comment` routed through the proxied server while the assembled provider type lacks Commenter() — stale server binary, mixed client/server versions, or a custom provider implementing only part of the source interfaces.","commonSituations":"Server built from an older commit predating the Commenter surface; deployment where the CLI was upgraded but the server wasn't restarted/rebuilt.","solutions":["Rebuild and restart the proxied server from the same commit as the bd CLI","Update the provider implementation to satisfy uow.CommenterSource (add a Commenter() method)","Pin CLI and server versions together in deployment","Use local (non-proxied) comment add as a workaround until versions align"],"exampleFix":"// before\ntype MyProvider struct{} // no Commenter method\n// after\nfunc (p *MyProvider) Commenter() (issueops.Commenter, error) { return p.store, nil }","handlingStrategy":"type-guard","validationCode":"bd --version  # verify CLI/server version parity before proxied comments","typeGuard":"if _, ok := provider.(uow.CommenterSource); !ok {\n    // use local comment path instead\n}","tryCatchPattern":"if err := addComment(); strings.Contains(err.Error(), \"does not offer the add-comment surface\") {\n    // rebuild/upgrade server, then retry\n}","preventionTips":["Build and deploy CLI and server together","Restart server processes after upgrades","Ensure custom providers implement CommenterSource","Cover proxied comment add in integration tests"],"tags":["proxied-server","interface-mismatch","comments"],"backgroundTag":"interface-not-implemented","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}