{"record":{"id":"9cf93f83567fc825","repo":"vxcontrol/pentagi","slug":"file-s-size-d-exceeds-maximum-allowed-size-d","errorCode":null,"errorMessage":"file '%s' size %d exceeds maximum allowed size %d","messagePattern":"file '(.+?)' size (.+?) exceeds maximum allowed size (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/terminal.go","lineNumber":406,"sourceCode":"\t\t\treturn \"\", fmt.Errorf(\"failed to read tar header: %w\", err)\n\t\t}\n\n\t\tif tarHeader.FileInfo().IsDir() {\n\t\t\tcontinue\n\t\t}\n\n\t\tif stats.Mode.IsDir() {\n\t\t\tbuffer.WriteString(\"--------------------------------------------------\\n\")\n\t\t\tbuffer.WriteString(\n\t\t\t\tfmt.Sprintf(\"'%s' file content (with size %d bytes) shown below:\\n\",\n\t\t\t\t\ttarHeader.Name, tarHeader.Size,\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\n\t\tconst maxReadFileSize int64 = 100 * 1024 * 1024 // 100 MB limit\n\t\tif tarHeader.Size > maxReadFileSize {\n\t\t\treturn \"\", fmt.Errorf(\"file '%s' size %d exceeds maximum allowed size %d\", tarHeader.Name, tarHeader.Size, maxReadFileSize)\n\t\t}\n\t\tif tarHeader.Size < 0 {\n\t\t\treturn \"\", fmt.Errorf(\"file '%s' has invalid size %d\", tarHeader.Name, tarHeader.Size)\n\t\t}\n\n\t\tvar fileContent = make([]byte, tarHeader.Size)\n\t\t_, err = tarReader.Read(fileContent)\n\t\tif err != nil && err != io.EOF {\n\t\t\treturn \"\", fmt.Errorf(\"failed to read file '%s' content: %w\", tarHeader.Name, err)\n\t\t}\n\t\tbuffer.Write(fileContent)\n\n\t\tif stats.Mode.IsDir() {\n\t\t\tbuffer.WriteString(\"\\n\\n\")\n\t\t}\n\t}\n\n\treturn buffer.String(), nil","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/terminal.go#L388-L424","documentation":"readFileFromContainer enforces a hard 100 MB cap (maxReadFileSize) on any single file pulled out of the container via CopyFromContainer. If the tar header reports a size above the cap the read is refused with this error, protecting the caller (an LLM tool result) and host memory from unbounded allocations (`make([]byte, tarHeader.Size)`).","triggerScenarios":"ReadFile or EditFile invoked on a file whose tar-reported size exceeds 104857600 bytes — e.g. large packet captures, core dumps, extracted archives, log files, or datasets accumulated in the sandbox container during a pentest.","commonSituations":"An agent tool call tries to read a multi-hundred-MB pcap or wordlist output; a binary artifact (memory dump, image) grew during the flow; EditFile targets a file that was appended to beyond the limit between reads.","solutions":["Read only what you need: `docker exec <container> head/tail/grep -m1 -c ...` or `sed -n '1,100p' <path>` instead of the whole file","Compress the file inside the container first (`gzip -c file > file.gz`) and read the smaller artifact, or split it (`split -b 50m`)","If the size is legitimately needed, copy the file out via a volume mount or `docker cp` on the host instead of the tool API","Raise maxReadFileSize in terminal.go only with an explicit memory budget — the buffer is allocated fully in RAM"],"exampleFix":"// before\ncontent, _ := tool.ReadFile(ctx, flowID, \"/captures/full.pcap\")\n// after\nout, _ := t.exec(ctx, flowID, \"tcpdump -r /captures/full.pcap -c 1000 -nn\") // bounded excerpt\n// or inside terminal.go: stream in chunks instead of make([]byte, tarHeader.Size)","handlingStrategy":"validation","validationCode":"size, err := executor.Run(ctx, flowID, fmt.Sprintf(\"stat -c %%s %s\", path))\nn, _ := strconv.ParseInt(strings.TrimSpace(size), 10, 64)\nif n > 100*1024*1024 {\n    return fmt.Errorf(\"file %s is %d bytes; read a subset instead\", path, n)\n}","typeGuard":"func withinReadLimit(size int64) bool {\n    const maxReadFileSize int64 = 100 * 1024 * 1024\n    return size >= 0 && size <= maxReadFileSize\n}","tryCatchPattern":"content, err := tool.ReadFile(ctx, flowID, path)\nif err != nil && strings.Contains(err.Error(), \"exceeds maximum allowed size\") {\n    // fall back to head/tail/grep for a bounded excerpt\n    content, err = tool.Execute(ctx, flowID, fmt.Sprintf(\"head -c 1M %s\", path))\n}","preventionTips":["Stat the file size before reading large artifacts","Prefer bounded reads (head, tail, grep) over whole-file reads","Compress or split oversized files in the container first","Never point the tool at pcaps, dumps, or archives without size checks"],"tags":["docker","size-limit","memory"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}