{"record":{"id":"8650ee05150ccc3a","repo":"infiniflow/ragflow","slug":"tenki-sandbox-is-no-longer-available-exc","errorCode":null,"errorMessage":"Tenki sandbox is no longer available: {exc}","messagePattern":"Tenki sandbox is no longer available: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agent/sandbox/providers/tenki.py","lineNumber":221,"sourceCode":"\n        args_json = json.dumps(arguments or {}, ensure_ascii=False)\n        script_path, argv = self._prepare_script(sandbox, remote_work_dir, normalized_lang, code, args_json)\n\n        requested_timeout = self.timeout if timeout is None else int(timeout)\n        if requested_timeout <= 0:\n            raise RuntimeError(f\"Execution timeout must be greater than 0 seconds, got {requested_timeout}.\")\n        exec_timeout = min(requested_timeout, self.timeout)\n\n        start_time = time.time()\n        try:\n            result = sandbox.exec(*argv, cwd=remote_work_dir, timeout=exec_timeout)\n        except (errors.CommandTimeoutError, errors.PrimitiveTimeoutError) as exc:\n            logger.warning(\"Tenki execution timed out (instance=%s, timeout=%ss)\", instance_id, exec_timeout)\n            raise TimeoutError(f\"Execution timed out after {exec_timeout} seconds\") from exc\n        except (errors.SessionTerminatedError, errors.SessionNotFoundError) as exc:\n            # The sandbox was reclaimed (e.g. max_lifetime) or lost mid-run;\n            # surface it as RuntimeError per the base contract, not an SDK type.\n            raise RuntimeError(f\"Tenki sandbox is no longer available: {exc}\") from exc\n        except Exception as exc:\n            raise RuntimeError(f\"Tenki execution failed: {exc}\") from exc\n        execution_time = time.time() - start_time\n\n        stdout = result.stdout_text\n        stderr = result.stderr_text\n        exit_code = int(result.exit_code)\n\n        self._validate_output_size(stdout, stderr)\n        stdout, structured_result = extract_structured_result(stdout)\n\n        return ExecutionResult(\n            stdout=stdout,\n            stderr=stderr,\n            exit_code=exit_code,\n            execution_time=execution_time,\n            metadata={\n                \"instance_id\": instance_id,","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/sandbox/providers/tenki.py#L203-L239","documentation":"RuntimeError raised when sandbox.exec() throws errors.SessionTerminatedError or errors.SessionNotFoundError: the microVM backing the instance is gone. Per the code comment, typical causes are the sandbox being reclaimed at max_lifetime or lost mid-run; it is deliberately surfaced as RuntimeError, not an SDK type.","triggerScenarios":"Calling execute_code() on an instance whose sandbox exceeded max_lifetime (default 3600s) and was reaped by Tenki, or on an instance terminated server-side (host maintenance, eviction). The provider's in-memory _instances registry still lists it.","commonSituations":"Long-lived agent sessions reusing one sandbox past its lifetime, a crashed/evicted microVM, or stale instance ids after the provider process resumed from a checkpoint.","solutions":["Recover by destroying the dead instance handle and create_instance() + execute_code() again (the work dir is per-instance, so re-upload/re-run the script).","Keep total instance age under max_lifetime; set max_lifetime in initialize() high enough for your session length.","Create a fresh instance per task instead of caching instances across long pauses."],"exampleFix":"# before\nresult = provider.execute_code(instance_id, code)  # raises after max_lifetime reclaim\n\n# after\ntry:\n    result = provider.execute_code(instance_id, code)\nexcept RuntimeError as exc:\n    if \"no longer available\" not in str(exc):\n        raise\n    provider.destroy_instance(instance_id)\n    inst = provider.create_instance(template)\n    result = provider.execute_code(inst.instance_id, code)","handlingStrategy":"fallback","validationCode":"# track instance age and refresh before max_lifetime reaps it\nage = time.time() - created_at[instance_id]\nif age > provider.max_lifetime - safety_margin:\n    refresh_instance(instance_id)","typeGuard":null,"tryCatchPattern":"try:\n    result = provider.execute_code(instance_id, code)\nexcept RuntimeError as exc:\n    if \"no longer available\" not in str(exc):\n        raise\n    provider.destroy_instance(instance_id)\n    inst = provider.create_instance(template)\n    result = provider.execute_code(inst.instance_id, code)  # fallback: fresh sandbox","preventionTips":["Set max_lifetime in initialize() above your longest session; recreate instances proactively before expiry.","One instance per task rather than long-lived shared sandboxes.","Make execute_code() callers idempotent so a sandbox-loss retry is safe."],"tags":["lifecycle","session-expiry","sandbox","tenki"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}