| "No program open" | Binary not loaded | Phase 0: load via curl or open_program |
| "Connection refused" | MCP server down | Restart bridge: bash /opt/ghidra-mcp/run-mcp.sh |
| Plate comment disappeared | Set prototype after comment | Re-apply comments — ordering law violated |
extraout_* / in_* variables | Decompiler artifacts | Skip in rename/type ops, note in plate comment |
| Variable rename fails silently | Register-only storage | force_decompile then retry, or use PRE_COMMENT |
| Name collision on rename | Duplicate name exists | search_functions_enhanced first, differentiate name |
Struct field shows undefined4 | Storage vs display mismatch | Normal — call set_local_variable_type explicitly |
batch_decompile timeout | Too many functions | Use smaller batches (10-20), not all at once |
| Thunk shows no body docs | JMP-only function documented | Document both thunk AND target body function |
create_function overlap error | Shared epilogue or existing body | Skip — code belongs to adjacent function |
| "No HighVariable found" | Stack arrays, decompiler composites | Skip on first failure, note in plate comment |
| Score < 50% | Severe documentation gaps | Flag for manual review, do not re-dispatch |
set_local_variable_type rejects no-op | Type must actually change | Verify current type differs from target before calling |
add_struct_field replaceAtOffset | Overlays undefined bytes | Only works on undefined/padding bytes — remove existing field first if occupied |
check_tools returns not_loaded | Tool group not active | Use connect_instance or load_tool_group to activate |
| Queries on a newly-loaded binary return the OLD binary's data | Loading does not switch; current_program still names the previous program | switch_program(name), verify is_current: true via list_open_programs, or pass program= explicitly |
| Two "different" binaries give identical addresses/xrefs | You are reading one binary | list_open_programs — do not trust get_current_program_info |
get_current_program_info shows a closed/wrong program | It returns cached data for a dead program | Use list_open_programs as source of truth |
| Second load of a same-named file "succeeds" but isn't there | Basename collision — silently lossy | Copy to distinct basenames (hw_steam.dll, hw_csns.dll) and reload |
run_analysis returns in ~1ms with new_functions: 0 | No-op on a load_program'd program (v4 headless); a huge count returned instantly is a CACHED count | Don't assume it analyzed. Use the byte-pattern workaround (see Pitfalls) or analyzeHeadless on the CLI |
get_function_by_address says "No function found" at an address nm gave you | .so/PIE image base not added | Add image_base from list_open_programs (commonly 0x10000); verify on two known symbols |
search_byte_patterns for a string's absolute address returns nothing, but the string IS used | 32-bit PIC — data is reached GOT-relative, never by absolute address | Search disp = (target - got_base) instead; try .got AND .got.plt |
search_memory_strings returns 0 even for a string you grepped out of the file | No strings defined — load_program does minimal analysis. On v6 headless the tool is absent entirely, which looks the same from the caller | Use search_byte_patterns with ASCII hex; always run a known-present control first |
analyzeHeadless reports "Analysis succeeded" but your call site has no enclosing function | Auto-analysis under-covers large PIC .so (e.g. 3.7k functions for 7.5 MB .text) | Do not equate "succeeded" with "the functions you need exist". Script the decode over raw bytes (run_script_inline) instead of relying on function discovery |