{"record":{"id":"55ea5808d3c5247d","repo":"infiniflow/ragflow","slug":"tenki-execution-produced-more-than-self-max-artif","errorCode":null,"errorMessage":"Tenki execution produced more than {self.max_artifacts} artifacts.","messagePattern":"Tenki execution produced more than (.+?) artifacts\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agent/sandbox/providers/tenki.py","lineNumber":472,"sourceCode":"            return\n\n        # fs.list returns each entry's basename in `.path`, not an absolute\n        # path, so join it onto the directory being listed.\n        for entry in sorted(entries, key=lambda item: item.path):\n            name = posixpath.basename(entry.path)\n            remote_path = posixpath.join(current_dir, name)\n            relative_path = posixpath.join(relative_dir, name) if relative_dir else name\n\n            # Reject symlinks. `is_symlink` is not populated by every SDK\n            # release, so also inspect the stat mode bits as the reliable check.\n            if getattr(entry, \"is_symlink\", False) or stat.S_ISLNK(entry.mode or 0):\n                raise RuntimeError(f\"Artifact symlinks are not allowed: {relative_path}\")\n            if entry.is_dir:\n                self._collect_artifacts_recursive(sandbox, remote_path, relative_path, artifacts, depth + 1)\n                continue\n\n            if len(artifacts) >= self.max_artifacts:\n                raise RuntimeError(f\"Tenki execution produced more than {self.max_artifacts} artifacts.\")\n\n            size = int(entry.size or 0)\n            if size > self.max_artifact_bytes:\n                raise RuntimeError(f\"Artifact exceeds {self.max_artifact_bytes} bytes: {relative_path}\")\n\n            ext = os.path.splitext(name)[1].lower()\n            if ext not in ALLOWED_ARTIFACT_EXTENSIONS:\n                raise RuntimeError(f\"Unsupported artifact type: {relative_path}\")\n\n            content = sandbox.fs.read_bytes(remote_path)\n            artifacts.append(\n                {\n                    \"name\": relative_path,\n                    \"content_b64\": base64.b64encode(content).decode(\"ascii\"),\n                    \"mime_type\": mimetypes.guess_type(name)[0] or \"application/octet-stream\",\n                    \"size\": size,\n                }\n            )","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/sandbox/providers/tenki.py#L454-L490","documentation":"Raised during artifact collection when the number of collected files would exceed max_artifacts (default 20). Once the list already holds max_artifacts entries, the next file raises; the cap bounds memory and payload size when base64-encoding artifacts into the result.","triggerScenarios":"Script writes more than 20 files into artifacts/ — e.g. a loop emitting hundreds of PNGs, or copying a directory tree — and collection hits file number 21.","commonSituations":"Chart-generation code saving many small images, scraping jobs saving per-item files, or archive extraction into artifacts/ instead of selecting final outputs.","solutions":["Make the script keep only the top max_artifacts outputs (delete intermediates, or write a single archive-free summary file).","Raise max_artifacts in initialize() if the workload legitimately produces more files.","Consolidate: pack results into one .csv/.json artifact instead of many files."],"exampleFix":"# before\n# script: for i in range(500): plt.savefig(f'artifacts/frame_{i}.png')\n\n# after\n# script: plt.savefig('artifacts/summary.png'); df.to_json('artifacts/results.json')","handlingStrategy":"validation","validationCode":"# in generated code, prune artifacts to the cap before finishing:\n# files = sorted(pathlib.Path('artifacts').rglob('*'))\n# for p in files[provider.max_artifacts:]: p.unlink()","typeGuard":null,"tryCatchPattern":"try:\n    result = provider.execute_code(instance_id, code)\nexcept RuntimeError as exc:\n    if \"more than\" in str(exc) and \"artifacts\" in str(exc):\n        result = provider.execute_code(instance_id, consolidated_artifacts_version(code))\n    else:\n        raise","preventionTips":["Generate scripts that produce a small fixed set of final outputs (one .csv + one .png, say).","Delete intermediates inside the script before it exits.","Raise max_artifacts in initialize() only if the consumer actually needs every file."],"tags":["artifacts","limits","execution","tenki"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}