wavetermdev/waveterm · error
circular file cannot be ijson
Error message
circular file cannot be ijson
What it means
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.
Source
Thrown at pkg/filestore/blockstore.go:123
type FileData struct {
ZoneId string `json:"zoneid"`
Name string `json:"name"`
PartIdx int `json:"partidx"`
Data []byte `json:"data"`
}
func (FileData) UseDBMap() {}
// synchronous (does not interact with the cache)
func (s *FileStore) MakeFile(ctx context.Context, zoneId string, name string, meta wshrpc.FileMeta, opts wshrpc.FileOpts) error {
if opts.MaxSize < 0 {
return fmt.Errorf("max size must be non-negative")
}
if opts.Circular && opts.MaxSize <= 0 {
return fmt.Errorf("circular file must have a max size")
}
if opts.Circular && opts.IJson {
return fmt.Errorf("circular file cannot be ijson")
}
if opts.Circular {
if opts.MaxSize%partDataSize != 0 {
opts.MaxSize = (opts.MaxSize/partDataSize + 1) * partDataSize
}
}
if opts.IJsonBudget > 0 && !opts.IJson {
return fmt.Errorf("ijson budget requires ijson")
}
if opts.IJsonBudget < 0 {
return fmt.Errorf("ijson budget must be non-negative")
}
return withLock(s, zoneId, name, func(entry *CacheEntry) error {
if entry.File != nil {
return fs.ErrExist
}
now := time.Now().UnixMilli()
file := &WaveFile{View on GitHub (pinned to a4447c1563)
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.
Example fix
// before
opts := wshrpc.FileOpts{Circular: true, IJson: true}
// after
opts := wshrpc.FileOpts{Circular: true, IJson: false} // ring-buffer mode only Defensive patterns
Strategy: validation
Validate before calling
func validModeOpts(opts wshrpc.FileOpts) bool {
return !(opts.Circular && opts.IJson)
}
if !validModeOpts(opts) {
return fmt.Errorf("circular and ijson are mutually exclusive")
} Try / catch
if err := store.MakeFile(ctx, zoneId, name, meta, opts); err != nil {
if strings.Contains(err.Error(), "circular file cannot be ijson") {
opts.IJson = false // prefer circular mode
err = store.MakeFile(ctx, zoneId, name, meta, opts)
}
if err != nil {
return err
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ijson budget requires ijson
- max size must be non-negative
- circular file must have a max size
- ijson budget must be non-negative
- offset must be non-negative
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/560504e8fab83e69.
Report an issue: GitHub.