{"record":{"id":"eaf55be739559eed","repo":"wavetermdev/waveterm","slug":"ijson-budget-requires-ijson","errorCode":null,"errorMessage":"ijson budget requires ijson","messagePattern":"ijson budget requires ijson","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/filestore/blockstore.go","lineNumber":131,"sourceCode":"\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{\n\t\t\tZoneId:    zoneId,\n\t\t\tName:      name,\n\t\t\tSize:      0,\n\t\t\tCreatedTs: now,\n\t\t\tModTs:     now,\n\t\t\tOpts:      opts,\n\t\t\tMeta:      meta,\n\t\t}","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/filestore/blockstore.go#L113-L149","documentation":"IJsonBudget caps the number/size budget of ijson entries, so it is only meaningful when IJson mode is enabled. MakeFile rejects IJsonBudget > 0 with IJson = false because the budget could never be applied.","triggerScenarios":"Calling MakeFile with opts.IJsonBudget set to a positive value while opts.IJson is false — usually by populating the whole FileOpts struct from a config/map where the budget key is present but the ijson flag was not enabled.","commonSituations":"Merging default FileOpts (which carry a nonzero IJsonBudget) with mode flags that disable ijson; a UI toggle turning ijson off while leaving the previously set budget in place; hand-written opts literals that set the budget but forget the flag.","solutions":["Set opts.IJson = true whenever a positive IJsonBudget is intended.","Reset IJsonBudget to 0 when ijson mode is disabled.","When deriving opts from config, validate the pair (ijson, ijsonBudget) together before calling MakeFile."],"exampleFix":"// before\nopts := wshrpc.FileOpts{IJsonBudget: 100} // IJson not set\n// after\nopts := wshrpc.FileOpts{IJson: true, IJsonBudget: 100}","handlingStrategy":"validation","validationCode":"func validIJsonBudget(opts wshrpc.FileOpts) bool {\n\treturn opts.IJsonBudget <= 0 || opts.IJson\n}\nif !validIJsonBudget(opts) {\n\treturn fmt.Errorf(\"ijsonBudget set without ijson\")\n}","typeGuard":null,"tryCatchPattern":"if err := store.MakeFile(ctx, zoneId, name, meta, opts); err != nil {\n\tif strings.Contains(err.Error(), \"ijson budget requires ijson\") {\n\t\topts.IJson = true\n\t\terr = store.MakeFile(ctx, zoneId, name, meta, opts)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n}","preventionTips":["Set IJson and IJsonBudget together as a pair.","Reset IJsonBudget to 0 when ijson mode is disabled.","Validate option pairs in a normalize step before MakeFile.","Avoid merging partial FileOpts structs that carry stale budgets."],"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"}