---
title: "debug.getproto"
description: "Returns a cloned nested prototype closure, or live matching closures when active is true."
---

```lua
debug.getproto(target: function | number, index: number, active: boolean? = false): function | {function} | nil
```

---

## Aliases

- `getproto`

---

## Arguments

<ParamField body="target" type="function | number" required>
  The function to inspect, or a positive stack level identifying a caller.
</ParamField>

<ParamField body="index" type="number" required>
  A 1-based slot index.
</ParamField>

<ParamField body="active" type="boolean" default={"false"}>
  Select the active prototype mode. The behavior differs between getproto and getprotos.
</ParamField>

---

## Returns

<ResponseField name="prototype" type="function | {function} | nil">
  A cloned nested closure, live matching closures in active mode, or nil.
</ResponseField>

active=false returns a new closure; true scans GC for closures using that prototype. Cloned closures do not guarantee initialized captured upvalues; do not blindly invoke them.

**Related types:** [Debug types & behavior](/reference/debug/types).

---

## Example

```lua
local function outer() return function() return "nested" end end
local live = outer()
local matches = debug.getproto(outer, 1, true)
print(type(matches), live())
```
