{"record":{"id":"510286b8996fc90f","repo":"golang/go","slug":"compressor-already-registered","errorCode":null,"errorMessage":"compressor already registered","messagePattern":"compressor already registered","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/archive/zip/register.go","lineNumber":129,"sourceCode":"\tcompressors.Store(Deflate, Compressor(func(w io.Writer) (io.WriteCloser, error) { return newFlateWriter(w), nil }))\n\n\tdecompressors.Store(Store, Decompressor(io.NopCloser))\n\tdecompressors.Store(Deflate, Decompressor(newFlateReader))\n}\n\n// RegisterDecompressor allows custom decompressors for a specified method ID.\n// The common methods [Store] and [Deflate] are built in.\nfunc RegisterDecompressor(method uint16, dcomp Decompressor) {\n\tif _, dup := decompressors.LoadOrStore(method, dcomp); dup {\n\t\tpanic(\"decompressor already registered\")\n\t}\n}\n\n// RegisterCompressor registers custom compressors for a specified method ID.\n// The common methods [Store] and [Deflate] are built in.\nfunc RegisterCompressor(method uint16, comp Compressor) {\n\tif _, dup := compressors.LoadOrStore(method, comp); dup {\n\t\tpanic(\"compressor already registered\")\n\t}\n}\n\nfunc compressor(method uint16) Compressor {\n\tci, ok := compressors.Load(method)\n\tif !ok {\n\t\treturn nil\n\t}\n\treturn ci.(Compressor)\n}\n\nfunc decompressor(method uint16) Decompressor {\n\tdi, ok := decompressors.Load(method)\n\tif !ok {\n\t\treturn nil\n\t}\n\treturn di.(Decompressor)\n}","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/archive/zip/register.go#L111-L147","documentation":"`zip.RegisterCompressor(method, comp)` is the encoding-side twin of RegisterDecompressor. It panics if a compressor for `method` is already in the global `compressors` map (Store and Deflate are pre-registered by `init`). Same global-state/once-only contract.","triggerScenarios":"Registering a compressor for `zip.Store` or `zip.Deflate`; registering a custom method (e.g. 12) twice; library + program both registering the same method; re-running registration inside a test loop without a guard.","commonSituations":"Two codecs packages registered via blank-import in the same binary; an `init()` in a vendored fork duplicating the upstream init; tests that re-init the codec map.","solutions":["Register each method exactly once; use `sync.Once` or a package-level flag.","Do not override `zip.Store`/`zip.Deflate` — they are wired by the package's own init.","Consolidate codec registration into a single package imported by everyone who needs it."],"exampleFix":"// before\nfunc init() {\n    zip.RegisterCompressor(12, bzip2Writer) // panics on duplicate import\n}\n// after\nvar bzip2Reg sync.Once\nfunc RegisterBzip2() {\n    bzip2Reg.Do(func() { zip.RegisterCompressor(12, bzip2Writer) })\n}","handlingStrategy":"validation","validationCode":"var regComp sync.Once\nregComp.Do(func() { zip.RegisterCompressor(12, newBzip2Writer) })","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register each custom method exactly once at startup.","Use sync.Once to make registration idempotent across import paths."],"tags":["archive","zip","panic","registration","global-state"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}