multica-ai/multica · error

read file: %w

Error message

read file: %w

What it means

Wrapped error from os.ReadFile when the avatar file passed the earlier existence/extension/size checks but could not be read into memory — deleted or truncated between stat and read, or read permission revoked. The %w is a *fs.PathError with the OS cause.

Source

Thrown at server/cmd/multica/cmd_agent.go:936

		return fmt.Errorf("file not found: %w", err)
	}

	// Validate extension.
	ext := strings.ToLower(filepath.Ext(filePath))
	validExts := map[string]bool{".png": true, ".jpg": true, ".jpeg": true, ".gif": true, ".webp": true}
	if !validExts[ext] {
		return fmt.Errorf("unsupported file format %q: must be .png, .jpg, .jpeg, .gif, or .webp", ext)
	}

	// Client-side size guard: reject files > 5MB.
	const maxSize = 5 << 20 // 5 MB
	if info.Size() > maxSize {
		return fmt.Errorf("file too large: %d bytes (max 5MB)", info.Size())
	}

	fileData, err := os.ReadFile(filePath)
	if err != nil {
		return fmt.Errorf("read file: %w", err)
	}

	// Defensive re-check: guard against TOCTOU race where the file
	// was swapped between stat and read.
	if len(fileData) > maxSize {
		return fmt.Errorf("file too large: %d bytes (max 5MB)", len(fileData))
	}

	ctx, cancel := context.WithTimeout(context.Background(), cli.AtLeastAPITimeout(60*time.Second))
	defer cancel()

	// Agent existence pre-check.
	var agent map[string]any
	if err := client.GetJSON(ctx, "/api/agents/"+args[0], &agent); err != nil {
		return fmt.Errorf("get agent: %w", err)
	}

	id, url, err := client.UploadFileWithURL(ctx, fileData, filePath)

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Check permissions: `ls -l <file>` and `chmod u+r <file>` if missing read access
  2. If the file is transient, copy it to a stable local path first (`cp /tmp/x.png ./avatar.png`) and retry
  3. Verify the file still exists and is non-empty right before the command in scripts
  4. Run as a user with read access to the file (or chown it)

Example fix

# before
multica agent avatar agt_1 --file /mnt/share/av.png
# Error: read file: open /mnt/share/av.png: permission denied

# after
cp /mnt/share/av.png ./av.png && chmod u+r ./av.png
multica agent avatar agt_1 --file ./av.png
Defensive patterns

Strategy: validation

Validate before calling

[ -r "$AVATAR_FILE" ] || { echo "cannot read $AVATAR_FILE"; exit 1; }
multica agent avatar "$AGENT_ID" --file "$AVATAR_FILE"

Try / catch

fileData, err := os.ReadFile(filePath)
if err != nil {
	return fmt.Errorf("read file: %w", err)
}

Prevention

When it happens

Trigger: The file is removed, truncated, or chmod'd to 000 in the window between os.Stat and os.ReadFile inside runAgentAvatar; more commonly, read permission is missing even though directory listing made Stat succeed.

Common situations: Temporary files being garbage-collected mid-command, editors swapping files on save, files on network mounts that vanish, or ownership mismatches (file owned by another user, mode 640).

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/fe02dea5abf709fc. Report an issue: GitHub.