{"record":{"id":"560504e8fab83e69","repo":"wavetermdev/waveterm","slug":"circular-file-cannot-be-ijson","errorCode":null,"errorMessage":"circular file cannot be ijson","messagePattern":"circular file cannot be ijson","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/filestore/blockstore.go","lineNumber":123,"sourceCode":"type FileData struct {\n\tZoneId  string `json:\"zoneid\"`\n\tName    string `json:\"name\"`\n\tPartIdx int    `json:\"partidx\"`\n\tData    []byte `json:\"data\"`\n}\n\nfunc (FileData) UseDBMap() {}\n\n// synchronous (does not interact with the cache)\nfunc (s *FileStore) MakeFile(ctx context.Context, zoneId string, name string, meta wshrpc.FileMeta, opts wshrpc.FileOpts) error {\n\tif opts.MaxSize < 0 {\n\t\treturn fmt.Errorf(\"max size must be non-negative\")\n\t}\n\tif opts.Circular && opts.MaxSize <= 0 {\n\t\treturn fmt.Errorf(\"circular file must have a max size\")\n\t}\n\tif opts.Circular && opts.IJson {\n\t\treturn fmt.Errorf(\"circular file cannot be ijson\")\n\t}\n\tif opts.Circular {\n\t\tif opts.MaxSize%partDataSize != 0 {\n\t\t\topts.MaxSize = (opts.MaxSize/partDataSize + 1) * partDataSize\n\t\t}\n\t}\n\tif opts.IJsonBudget > 0 && !opts.IJson {\n\t\treturn fmt.Errorf(\"ijson budget requires ijson\")\n\t}\n\tif opts.IJsonBudget < 0 {\n\t\treturn fmt.Errorf(\"ijson budget must be non-negative\")\n\t}\n\treturn withLock(s, zoneId, name, func(entry *CacheEntry) error {\n\t\tif entry.File != nil {\n\t\t\treturn fs.ErrExist\n\t\t}\n\t\tnow := time.Now().UnixMilli()\n\t\tfile := &WaveFile{","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/filestore/blockstore.go#L105-L141","documentation":"IJson files carry per-item JSON metadata that has no place in a circular ring buffer layout, so the combination is structurally unsupported. MakeFile rejects Circular && IJson early to avoid creating a file whose format invariants conflict.","triggerScenarios":"Calling MakeFile with both opts.Circular = true and opts.IJson = true — e.g. merging option sets where one enables circular buffering and another enables ijson mode.","commonSituations":"Building FileOpts from user preferences where both toggles are independently exposed; a caller migrating an ijson file to circular for retention without realizing the formats are mutually exclusive; copy-pasted opts structs accumulating flags.","solutions":["Choose one mode: keep IJson=false if you need a fixed-size circular file, or keep Circular=false if you need ijson.","If you need both bounded size and structured JSON records, implement trimming at the application level instead of circular mode.","Split into two files: a circular file for raw data plus a separate ijson file for metadata."],"exampleFix":"// before\nopts := wshrpc.FileOpts{Circular: true, IJson: true}\n// after\nopts := wshrpc.FileOpts{Circular: true, IJson: false} // ring-buffer mode only","handlingStrategy":"validation","validationCode":"func validModeOpts(opts wshrpc.FileOpts) bool {\n\treturn !(opts.Circular && opts.IJson)\n}\nif !validModeOpts(opts) {\n\treturn fmt.Errorf(\"circular and ijson are mutually exclusive\")\n}","typeGuard":null,"tryCatchPattern":"if err := store.MakeFile(ctx, zoneId, name, meta, opts); err != nil {\n\tif strings.Contains(err.Error(), \"circular file cannot be ijson\") {\n\t\topts.IJson = false // prefer circular mode\n\t\terr = store.MakeFile(ctx, zoneId, name, meta, opts)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n}","preventionTips":["Expose circular and ijson as mutually exclusive options in your UI/config.","Document the mutual exclusion wherever FileOpts is built.","Validate combined flags in a single normalizeOpts helper before store calls.","Prefer application-level trimming over circular mode when structured records are needed."],"tags":["validation","filestore","incompatible-options"],"backgroundTag":"invalid-argument-value","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}