wavetermdev/waveterm · error

max size must be non-negative

Error message

max size must be non-negative

What it means

FileStore.MakeFile validates FileOpts before creating a file in the block store. A negative MaxSize is nonsensical (it would mean an unbounded-negative capacity), so MakeFile rejects it up front with this error instead of creating a corrupt or unusable file.

Source

Thrown at pkg/filestore/blockstore.go:117

	newFile.Meta = copyMeta(f.Meta)
	return &newFile
}

func (WaveFile) UseDBMap() {}

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")
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Fix the caller to pass MaxSize >= 0; use 0 for 'no cap' semantics for non-circular files.
  2. If using -1 as an 'unlimited' sentinel, translate it before calling: if max < 0 { max = 0 }.
  3. Clamp parsed user input: opts.MaxSize = max(0, parsedSize).

Example fix

// before
opts := wshrpc.FileOpts{MaxSize: -1} // 'unlimited'
err := store.MakeFile(ctx, zoneId, name, meta, opts)
// after
maxSize := int64(-1)
if maxSize < 0 {
	maxSize = 0
}
opts := wshrpc.FileOpts{MaxSize: maxSize}
err := store.MakeFile(ctx, zoneId, name, meta, opts)
Defensive patterns

Strategy: validation

Validate before calling

func validMaxSize(max int64) bool { return max >= 0 }
if !validMaxSize(opts.MaxSize) {
	return fmt.Errorf("caller bug: MaxSize must be >= 0")
}

Try / catch

if err := store.MakeFile(ctx, zoneId, name, meta, opts); err != nil {
	if strings.Contains(err.Error(), "max size must be non-negative") {
		opts.MaxSize = 0
		err = store.MakeFile(ctx, zoneId, name, meta, opts)
	}
	if err != nil {
		return err
	}
}

Prevention

When it happens

Trigger: Calling MakeFile with wshrpc.FileOpts where opts.MaxSize < 0 — e.g. MaxSize defaulting to -1 in caller code, a subtraction underflow, or a user-supplied size parsed and negated.

Common situations: Callers using -1 as a sentinel for 'unlimited' size (MaxSize has no such meaning here); computing MaxSize from a config value minus overhead where the overhead exceeds the value; deserializing options where MaxSize was omitted and becomes a negative default.

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


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/3c5edb4aeb927516. Report an issue: GitHub.