# How to Debug SkillSpector Using LangGraph Studio: A Step-by-Step Guide

> Debug SkillSpector efficiently with LangGraph Studio. Step through node-by-node, inspect SkillSpectorState, and pinpoint analyzer or LLM call bugs. Easy, actionable guide.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: how-to-guide
- Published: 2026-06-20

---

**Run `make langgraph-dev` to launch LangGraph Studio, then step through the SkillSpector workflow node-by-node while inspecting the evolving `SkillspectorState` to isolate bugs in analyzers or LLM calls.**

SkillSpector is a security analysis tool built as a **LangGraph workflow** by NVIDIA. The entire graph is defined in [`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py) and all shared state is managed through the typed dictionary in [`src/skillspector/state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/state.py). Developers can debug SkillSpector using LangGraph Studio to visualize execution flow, inject custom inputs, and examine intermediate state without writing print statements or restarting the CLI.

## Launch the LangGraph Development Server

Start the local development server using the Makefile target:

```bash
make langgraph-dev

```

This command launches a FastAPI server that loads the LangGraph definition from [`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py) and opens **LangGraph Studio** in your browser. The terminal displays the local URL (typically `http://127.0.0.1:2024`). Ensure you have configured your environment variables in a `.env` file or exported them directly—such as `SKILLSPECTOR_PROVIDER` and `OPENAI_API_KEY`—as documented in [`docs/DEVELOPMENT.md`](https://github.com/NVIDIA/SkillSpector/blob/main/docs/DEVELOPMENT.md).

## Inspect the Graph Layout

Once Studio loads, the interface renders a Mermaid diagram representing the workflow logic. The execution flow follows this sequence:

1. `resolve_input` – Validates and localizes the target skill
2. `build_context` – Scans files and populates metadata
3. Parallel analyzer nodes (e.g., `static_yara`, `behavioral_ast`) – Run security checks
4. `meta_analyzer` – Optional LLM-based filtering of findings
5. `report` – Generates final output and risk scoring

Each node corresponds to a Python module in `src/skillspector/nodes/`, allowing you to cross-reference the visual graph with the underlying implementation.

## Configure Custom Input Payloads

The graph expects a JSON payload containing either an `input_path` (URL, zip, file, or directory) or a pre-resolved `skill_path`. In LangGraph Studio’s **Run** panel, paste a configuration like:

```json
{
  "input_path": "/path/to/my/skill",
  "output_format": "json",
  "use_llm": false
}

```

Setting `use_llm` to `false` disables the `meta_analyzer` step, significantly speeding up iterative debugging. The `output_format` field accepts `terminal`, `json`, `markdown`, or `sarif`, controlling how the final node structures the report.

## Step Through Node Execution

LangGraph Studio allows interactive traversal of the graph. After triggering a run, click through each node to inspect the `SkillspectorState` dictionary in the right-hand pane.

### Resolve Input Node

The `resolve_input` node (implemented in [`src/skillspector/nodes/resolve_input.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/resolve_input.py)) handles URL downloads, zip extractions, and directory validation. If this node fails, check the state for `temp_dir_for_cleanup`—a path to extracted files that may reveal malformed archives or permission errors.

### Build Context Node

Next, `build_context` (in [`src/skillspector/nodes/build_context.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/build_context.py)) populates `components`, `file_cache`, `manifest`, and `component_metadata`. Verify that your skill files appear correctly in the `file_cache` dictionary before proceeding to analysis.

### Analyzer Nodes

Parallel analyzers registered in [`src/skillspector/nodes/analyzers/__init__.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/__init__.py) append `findings` to the state. Inspect the list after each analyzer runs:

- **Static analyzers** (e.g., `static_yara`, `static_patterns_prompt_injection`) search for hardcoded secrets or injection patterns
- **Behavioral analyzers** (e.g., `behavioral_ast`) parse abstract syntax trees for risky code paths

If a node returns an empty `findings` list unexpectedly, verify the corresponding analyzer implementation in the `src/skillspector/nodes/analyzers/` directory.

### Meta Analyzer and Report Nodes

When `use_llm` is enabled, the `meta_analyzer` node (in [`src/skillspector/nodes/meta_analyzer.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/meta_analyzer.py)) calls the configured LLM to filter false positives. Finally, the `report` node (in [`src/skillspector/nodes/report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py)) writes the `report_body`, `risk_score`, and `risk_severity` to the state based on the accumulated findings.

## Diagnose Common Issues

Use Studio’s state inspector to pinpoint failures without sifting through log files:

- **Missing inputs**: If `skill_path` is `None` after `resolve_input`, check the `temp_dir_for_cleanup` entry for extraction errors or invalid URLs.
- **Silent analyzers**: Empty `findings` lists following an analyzer node indicate the check did not match your test file—verify the analyzer’s logic in its dedicated module.
- **LLM errors**: Exceptions in `meta_analyzer` surface as explicit error messages in the node output; confirm your API keys are set correctly in the environment.

## Debug Programmatically (Alternative)

For developers preferring Python REPLs over the web UI, invoke the compiled graph directly:

```python
from skillspector import graph

result = graph.invoke({
    "input_path": "/path/to/skill",
    "output_format": "json",
    "use_llm": False,
})

print(result["risk_score"], result["risk_severity"])
print(result["report_body"])

```

This approach bypasses the Studio interface while still executing the full workflow defined in [`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py).

## Summary

- **Launch**: Run `make langgraph-dev` to start LangGraph Studio and load the workflow from [`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py).
- **Input**: Provide JSON payloads with `input_path` and set `use_llm: false` for faster iteration.
- **Inspect**: Step through `resolve_input`, `build_context`, analyzer nodes, and `report` to view the `SkillspectorState` evolution.
- **Fix**: Correlate empty states or errors with specific node implementations in `src/skillspector/nodes/`.

## Frequently Asked Questions

### How do I launch LangGraph Studio for SkillSpector debugging?

Execute `make langgraph-dev` from the repository root. This starts the FastAPI server and opens Studio in your browser, loading the graph definition from [`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py) and state schema from [`src/skillspector/state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/state.py).

### What JSON payload format does SkillSpector require in LangGraph Studio?

The graph accepts a dictionary containing `input_path` (string) and optional keys like `output_format` (`json`, `markdown`, `sarif`, or `terminal`) and `use_llm` (boolean). You can also pass `skill_path` directly if the input has already been resolved.

### How can I speed up debugging by skipping LLM calls?

Set `use_llm: false` in your input payload. This bypasses the `meta_analyzer` node entirely, allowing you to iterate quickly on static and behavioral analyzers without incurring API latency or costs.

### Where are temporary files managed during a debug session?

The `resolve_input` node writes extracted archives to a path stored in `temp_dir_for_cleanup` within the `SkillspectorState`. While the Studio server discards these on exit, you can manually inspect this path during a paused execution to verify extraction integrity.