{"record":{"id":"4ca9b7a381b89c51","repo":"JuliusBrussee/caveman","slug":"unknown-compression-codec-q","errorCode":null,"errorMessage":"unknown compression codec %q","messagePattern":"unknown compression codec %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/objectstore/compress.go","lineNumber":52,"sourceCode":"// Compress encodes data with the named codec. \"none\" returns data unchanged.\nfunc Compress(codec string, data []byte) ([]byte, error) {\n\tswitch codec {\n\tcase CompressionNone, \"\":\n\t\treturn data, nil\n\tcase CompressionGzip:\n\t\tvar buf bytes.Buffer\n\t\tzw := gzip.NewWriter(&buf)\n\t\tif _, err := zw.Write(data); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"gzip: %w\", err)\n\t\t}\n\t\tif err := zw.Close(); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"gzip close: %w\", err)\n\t\t}\n\t\treturn buf.Bytes(), nil\n\tcase CompressionZstd:\n\t\treturn zstdEnc.EncodeAll(data, nil), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown compression codec %q\", codec)\n\t}\n}\n\n// Decompress reverses Compress with a defensive default expansion ceiling. An\n// unknown codec fails closed.\nfunc Decompress(codec string, data []byte) ([]byte, error) {\n\treturn DecompressLimit(codec, data, DefaultMaxDecompressedBytes)\n}\n\n// DecompressLimit reverses Compress while refusing to produce more than\n// maxBytes of plaintext. The limit is applied while decoding gzip and through\n// zstd's decoder memory bound, so highly-compressible hostile payloads cannot\n// first allocate their full expanded size and only then be rejected.\nfunc DecompressLimit(codec string, data []byte, maxBytes int64) ([]byte, error) {\n\tif maxBytes < 0 || maxBytes > DefaultMaxDecompressedBytes {\n\t\treturn nil, fmt.Errorf(\"invalid decompression limit %d\", maxBytes)\n\t}\n\tswitch codec {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/objectstore/compress.go#L34-L70","documentation":"Compress was called with a codec string it does not recognize. The library only supports its named constants (none/\"\", gzip, zstd) and fails closed on anything else rather than silently storing uncompressed data. This is an argument-validation error; the %q formatting shows the offending codec value.","triggerScenarios":"Calling objectstore.Compress (or Decompress) with a codec string that is not one of CompressionNone, \"\", CompressionGzip, or CompressionZstd — e.g. a typo like \"gzp\", \"GZIP\" (case-sensitive), a value from user input, or a codec read from untrusted metadata.","commonSituations":"Storing the codec in a database/config with a different casing or spelling, an older client writing new codec names a newer build removed (or vice versa), or user-supplied compression preferences not validated before use.","solutions":["Log/inspect the %q value in the error to see the exact offending codec string.","Use the library's exported constants (CompressionGzip, CompressionZstd, CompressionNone) instead of raw string literals.","Normalize user-supplied codec names (trim, lowercase) and map them to constants before calling.","Add a validation step at config/ingest time that rejects unknown codec names early.","Check stored records for legacy codec spellings and migrate them to supported values."],"exampleFix":"// before\nobjectstore.Compress(cfg.Compression, data) // cfg.Compression = \"GZIP\" from config\n// after\nswitch strings.ToLower(cfg.Compression) {\ncase \"gzip\":\n    cfg.Compression = objectstore.CompressionGzip\ncase \"zstd\":\n    cfg.Compression = objectstore.CompressionZstd\ncase \"\", \"none\":\n    cfg.Compression = objectstore.CompressionNone\ndefault:\n    return fmt.Errorf(\"unsupported compression setting %q\", cfg.Compression)\n}\nout, err := objectstore.Compress(cfg.Compression, data)","handlingStrategy":"validation","validationCode":"var supported = map[string]bool{\n    objectstore.CompressionGzip: true,\n    objectstore.CompressionZstd: true,\n    objectstore.CompressionNone: true,\n    \"\":                          true,\n}\nif !supported[codec] {\n    return fmt.Errorf(\"unsupported compression codec %q\", codec)\n}\nout, err := objectstore.Compress(codec, data)","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var uv *fmt.Errorf // inspect the %q codec name in the message\n    return fmt.Errorf(\"config: compression codec rejected by objectstore: %w\", err)\n}","preventionTips":["Always use the library's exported codec constants, never raw literals.","Validate codec values at config-load or API-ingest time.","Normalize user input (trim, lowercase) and map to constants before calling.","Add a startup assertion that the configured codec is supported."],"tags":["compression","validation","go","objectstore"],"backgroundTag":"invalid-enum-value","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}