gastownhall/beads · error
proxied-server provider %T does not offer the issue-lifecycl
Error message
proxied-server provider %T does not offer the issue-lifecycle surface
What it means
On the proxied-server route, commands reach storage through a unit-of-work provider. proxiedIssueLifecycle requires that provider to also implement uow.IssueLifecycleSource; when the concrete provider type does not, the issue-lifecycle operations (create/reopen/update via issueops.Lifecycle) cannot proceed and this error names the actual provider type to aid diagnosis.
Source
Thrown at cmd/bd/update_proxied_server.go:78
if jsonOut && len(updated) > 0 {
_ = outputJSON(updated)
}
if len(failures) > 0 {
return reportUpdateFailures(failures, len(args))
}
return nil
}
// proxiedIssueLifecycle asks the unit-of-work provider for the write role, the
// same way proxiedIssueReader asks it for the read one.
func proxiedIssueLifecycle() (issueops.Lifecycle, error) {
if uowProvider == nil {
return nil, errors.New("proxied-server UOW provider not initialized")
}
src, ok := uowProvider.(uow.IssueLifecycleSource)
if !ok {
return nil, fmt.Errorf("proxied-server provider %T does not offer the issue-lifecycle surface", uowProvider)
}
return src.IssueLifecycle()
}
// applyUpdateProxiedOne applies one issue's update — plain or --claim —
// through issueops.Lifecycle. What stays here is this surface's own protocol:
// the template guard, the advisory reassign pre-read, the per-id failure
// taxonomy the multi-id batch needs and the notes-overwrite warning. Hooks are
// NOT among them: they fire from the write plumbing now (the notifying provider
// wired in main.go), which is what makes an update fire the same events here as
// it does on the embedded path.
//
// Provenance carries the commit message this path has always written, so `bd
// dolt log` reads the same after the move as before it. The plane is
// deliberately NOT restricted: `bd update` has always resolved a wisp id,
// unlike the HTTP claim endpoint, which serves durable issues only.
//
// The pre-read is a read of its own, one transaction earlier than theView on GitHub (pinned to 71377f2769)
Solutions
- Upgrade the proxied server to a build whose provider implements IssueLifecycleSource
- Check server/provider configuration and restart the proxied server
- Report the provider type (%T in the message) if it looks like a wiring bug
Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := uowProvider.(uow.IssueLifecycleSource); !ok {
return fmt.Errorf("provider %T lacks IssueLifecycleSource; upgrade server", uowProvider)
} Type guard
src, ok := uowProvider.(uow.IssueLifecycleSource)
if !ok {
return nil, fmt.Errorf("provider %T does not offer the issue-lifecycle surface", uowProvider)
}
return src.IssueLifecycle() Try / catch
if err := runUpdate(); err != nil {
if strings.Contains(err.Error(), "does not offer the issue-lifecycle surface") {
// fall back to direct (non-proxied) route or surface an upgrade hint
}
} Prevention
- Keep client and proxied-server builds on compatible versions
- Verify provider wiring at server startup
- Add startup-time interface assertions for required surfaces
When it happens
Trigger: Running create/reopen/update against a proxied server whose configured uowProvider lacks the IssueLifecycleSource interface — typically a mismatched or partially initialized server build/provider wiring.
Common situations: Version mismatch between bd client and proxied server; custom or stub provider injected in tests/embedded setups; server started with a provider that only implements a narrower surface.
Related errors
- proxied-server provider %T does not offer the batch-close su
- proxied-server provider %T does not offer the add-comment su
- proxied-server provider %T does not offer the batch-create s
- proxied-server provider %T does not offer the version-marker
- resolve proxied server root: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/d47b4bde8caca188.
Report an issue: GitHub.