Skip to content

fix(webdav): register chi REPORT method in init to avoid race with settings#2712

Open
SAY-5 wants to merge 1 commit intoopencloud-eu:mainfrom
SAY-5:fix/settings-service-init-2686
Open

fix(webdav): register chi REPORT method in init to avoid race with settings#2712
SAY-5 wants to merge 1 commit intoopencloud-eu:mainfrom
SAY-5:fix/settings-service-init-2686

Conversation

@SAY-5
Copy link
Copy Markdown

@SAY-5 SAY-5 commented May 5, 2026

Description

Move chi.RegisterMethod("REPORT") from webdav.NewService into a package
init() function so it runs before any service goroutine is spawned by the
suture supervisor.

Related Issue

Motivation and Context

Issue #2686 reports a runtime panic during settings-service HTTP server
initialisation, with the stack ending in chi/v5.(*node).setEndpoint
iterating a map (internal/runtime/maps.(*Iter).Next /
internal/runtime/maps.fatal).

chi.RegisterMethod mutates the package-level methodMap in
github.com/go-chi/chi/v5/tree.go:

methodMap[method] = mt
reverseMethodMap[mt] = method
mALL |= mt

(*node).setEndpoint reads that same global map during route insertion at
tree.go:359:

for _, m := range methodMap {
    h := n.endpoints.Value(m)
    ...
}

opencloud/pkg/runtime/service registers many services (webdav,
settings, activitylog, auth-app, ...) under a suture supervisor
and starts them concurrently. While webdav executed
chi.RegisterMethod("REPORT") inside NewService, another service
(here settings) could be in the middle of mux.Route(...)
MountInsertRoutesetEndpoint and iterating methodMap,
producing a "concurrent map iteration and map write" runtime fatal —
exactly the stack trace in the issue.

Moving the call into init() makes registration happen during package
import, which is sequential and well-ordered before any
suture-supervised goroutine starts. chi.RegisterMethod is idempotent
(returns early if the method is already registered), so it remains safe.

How Has This Been Tested?

  • test environment: go build ./... and go vet/gofmt on the affected
    package
  • test case 1: go build ./services/webdav/... ./services/settings/...
    succeeds
  • test case 2: go test -race ./services/webdav/pkg/service/v0/... builds
    cleanly under the race detector
  • test case 3: full repository go build ./... succeeds

I do not have a deterministic local reproducer for the original panic — it
was reported as an intermittent crash during container start — but the
race is straightforward to read off the chi source: a package-global map
written by RegisterMethod and iterated by setEndpoint.

Screenshots (if appropriate):

n/a

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Technical debt
  • Tests only (no source changes)

Checklist:

  • Code changes
  • Unit tests added
  • Acceptance tests added
  • Documentation added (changelog entry)

chi.RegisterMethod mutates a package-global methodMap in
github.com/go-chi/chi/v5 that (*node).setEndpoint also iterates during
route insertion. Calling it inside webdav.NewService at service start
races with route registration in concurrently-starting services such as
settings, triggering a 'concurrent map iteration and map write' Go
runtime panic in chi tree.go during HTTP server initialisation. Move
the call to package init so it runs before any suture-supervised
service goroutine is spawned.

Fixes opencloud-eu#2686

Signed-off-by: Sai Asish <saiasish.cnp@gmail.com>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Settings Service crashes during HTTP server initialization with a Go runtime panic in chi route registration

1 participant