A plugin throws Run time error 3 and either spams your log or crashes a feature mid-round. Error 3 is AMX_ERR_STACKERR — the Pawn virtual machine's stack collided with its heap. It is not random: it means a plugin tried to reserve more temporary memory than the VM has, and the fix is almost always to move a large buffer off the stack. Here is how to read it, locate the function, and repair the source.
1. Read the full log line first
Open addons/amxmodx/logs/ and find the entry. Unresolved, it looks like this:
[AMXX] Run time error 3 (plugin "myplugin.amxx") (native "...") - debug not enabled! [AMXX] To enable debug mode, add "debug" after the plugin name in plugins.ini (without quotes).
Without debug you only know which plugin failed, not where. That is the first thing to fix — you need the line number.
2. Enable debug to get the call trace
Edit addons/amxmodx/configs/plugins.ini and append debug after the failing plugin:
myplugin.amxx debug
Change the map so the plugin reloads, then reproduce the error. Now the log carries a full trace with function names and line numbers:
[AMXX] Displaying debug trace (plugin "myplugin.amxx") [AMXX] Run time error 3 (stack error) [AMXX] [0] myplugin.sma::BuildReport (line 142)
The general workflow for turning cryptic numbers into a line is covered in debugging AMXX plugins. Line 142 is where you look next.
3. Understand why the stack overflows
Pawn gives each plugin one region of memory that the stack grows down into and the heap grows up into. Local variables — anything declared with new inside a function — live on the stack. A big local array eats it fast:
public BuildReport(id)
{
new huge[8192] // 8192 cells = 32 KB on the stack, per call
// ...
}Declare a couple of those in nested functions, or recurse, and the stack runs into the heap. The VM aborts with error 3. It is a source problem, not a server misconfiguration.
4. Move large buffers off the stack
The correct fix is new static, which allocates the array once in the data segment instead of on the stack every call:
public BuildReport(id)
{
static huge[8192] // allocated once, not per call
// ...
}Use static for any local array over a few hundred cells and for buffers inside frequently called handlers. If you genuinely need a bigger stack — a menu builder with many moderate buffers, say — you can enlarge the whole region at the top of the .sma:
#pragma dynamic 32768
Raise it and recompile. Treat that as a second resort; converting arrays to static is the real cure and costs nothing at runtime.
5. Watch for recursion and format calls
Two other patterns trigger error 3. Unbounded recursion — a function that calls itself without a hard stop — consumes a stack frame each level until it collides. And formatting into an undersized buffer, then passing it around by value, multiplies stack use. Cap recursion depth explicitly and pass large strings by reference where the API allows it.
6. Catch it before it ships
Error 3 is preventable at compile time if you read the warnings. The compiler reports the estimated stack usage of each function and warns when a local array is large; do not ignore those lines. As a habit, treat any array over roughly 128 cells inside a function as a candidate for static, and keep menu and report builders — the functions that assemble long strings — under review, because they accumulate buffers quickly. A plugin that compiles with a comfortable stack margin will not throw error 3 under a full server, whereas one that compiles right at the edge fails only when several players hit the same handler at once. Fixing it in the source, once, beats chasing intermittent crashes on a live server.
Common errors
- "debug not enabled!" in every trace — you never added
debuginplugins.ini, so you are guessing at the line. Add it and reproduce. - Error 3 only under load — a per-player handler with a big local array; 20 players hitting it at once exhausts the stack. Make the array
static. - Recompiled but it still errors — the old
.amxxis still on disk. Confirm the new build deployed and the map changed; see updating plugins live. - Different number, same crash — run time error 4 is an array-bounds fault, not a stack fault. That one is covered separately.
- Only happens on one map — a map-specific config or entity count is pushing an already-marginal plugin over the edge; the stack was too small all along.
Verification
After converting the buffer and recompiling, redeploy, change the map, and drive the exact action that failed — open the menu, run the command, finish the round. Watch the log with the plugin still flagged debug: no new error 3 means the stack no longer collides. Once it is clean for a full map, remove the debug flag so the plugin runs at full JIT speed again. If the trace still points at a huge local, you missed one — grep the source for large new arrays inside functions and make them static.









