
Ai Fixing Errors
- 20 installs
- 11 repo stars
- Updated June 28, 2026
- lebsral/dspy-programming-not-prompting-lms-skills
Helps with ai & agent building tasks.
About
ai-fixing-errors is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- ai-fixing-errors
- AI & Agent Building
- AI-coding skill
Ai Fixing Errors by the numbers
- 20 all-time installs (skills.sh)
- Ranked #10,459 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/lebsral/dspy-programming-not-prompting-lms-skills --skill ai-fixing-errorsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 20 |
|---|---|
| repo stars | ★ 11 |
| Last updated | June 28, 2026 |
| Repository | lebsral/dspy-programming-not-prompting-lms-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Fix Your Broken AI
Systematic approach to diagnosing and fixing AI features that aren't working.
Step 1 — Gather context
Before debugging, ask the user:
1. What error message or unexpected behavior are you seeing? (paste the traceback or describe the output) 2. Did this work before, or is it a new feature that has never worked? 3. Are you using an optimizer, or is this a zero-shot / few-shot program? 4. What LM provider and model are you using?
Step 2 — Quick Diagnostic Checklist
1. Is the AI provider configured?
import dspy
# Check current config
print(dspy.settings.lm) # Should show your LM, not None
# If None, configure it:
lm = dspy.LM("openai/gpt-4o-mini") # or "anthropic/claude-sonnet-4-5-20250929", etc.
dspy.configure(lm=lm)Common issues:
- Forgot to call
dspy.configure(lm=lm) - API key not set in environment
- Wrong model name format (should be
provider/model-name)
2. Does the AI respond at all?
# Test the AI provider directly
lm = dspy.LM("openai/gpt-4o-mini") # or "anthropic/claude-sonnet-4-5-20250929", etc.
response = lm("Hello, respond with just 'OK'")
print(response)3. Is the task definition correct?
# Check your signature defines the right fields
class MySignature(dspy.Signature):
"""Clear task description here."""
input_field: str = dspy.InputField(desc="what this contains")
output_field: str = dspy.OutputField(desc="what to produce")
# Verify by inspecting
print(MySignature.fields)Common issues:
- Missing
dspy.InputField()/dspy.OutputField()annotations - Wrong type hints (use
str,list[str],Literal[...], Pydantic models) - Vague or missing docstring (the docstring IS the task instruction)
4. Are you passing the right inputs?
# Check that input field names match
result = my_program(question="test") # field name must match signature
# Wrong:
result = my_program(q="test") # 'q' doesn't match 'question'
result = my_program("test") # positional args don't work5. Is the output being parsed?
result = my_program(question="test")
print(result) # see all fields
print(result.answer) # access specific field
print(type(result.answer)) # check typeCommon issues with typed outputs:
Literaltype doesn't match any of the provided options- Pydantic model validation fails
- List output returns string instead of list
Inspect What the AI Actually Sees
The most powerful debugging tool — shows exactly what prompts were sent and what came back:
# Show the last 3 AI calls
dspy.inspect_history(n=3)This shows:
- The full prompt sent to the AI
- The AI's raw response
- How DSPy parsed the response
What to look for:
- Is the prompt clear? Does it describe the task well?
- Is the AI's response in the expected format?
- Are few-shot examples (if any) helpful or misleading?
Common Errors and Fixes
AttributeError: 'NoneType' has no attribute ...
Cause: AI provider not configured. Fix: Call dspy.configure(lm=lm) before using any module.
ValueError: Could not parse output
Cause: AI output doesn't match expected format. Fix:
- Check
dspy.inspect_history()to see what the AI returned - Simplify your output types
- Add clearer field descriptions
- Use
dspy.ChainOfThoughtinstead ofdspy.Predict(reasoning helps formatting)
TypeError: forward() got an unexpected keyword argument
Cause: Input field name mismatch. Fix: Make sure you're passing keyword arguments that match your signature's InputField names.
Search/retriever returns empty results
Cause: Retriever not configured or wrong endpoint. Fix:
# Test retriever directly
rm = dspy.ColBERTv2(url="http://...")
results = rm("test query", k=3)
print(results)
# Or if using a custom retriever function, call it directly to verifyOptimizer makes things worse
Cause: Bad metric, too little data, or overfitting. Fix:
- Manually verify your metric on 10-20 examples
- Add more training data
- Reduce
max_bootstrapped_demos - Use a validation set to check for overfitting
dspy.Refine not meeting threshold / exhausting attempts
Cause: Reward function threshold is too strict, or the module cannot produce outputs that score high enough. Fix:
- Check if the threshold is realistic for your graduated reward function (e.g.,
0.8rather than1.0for multi-criteria scoring) - Make the reward function more descriptive by returning partial scores rather than binary 0/1
- Ensure the module can reasonably produce outputs that satisfy the reward criteria
- Increase
Nto give more retry attempts, or usedspy.BestOfNfor independent sampling
Advanced Debugging
Enable verbose tracing
dspy.configure(lm=lm, trace=[])
# Now run your program — trace will be populated
result = my_program(question="test")Inspect module structure
# Print the module tree
print(my_program)
# See all named predictors
for name, predictor in my_program.named_predictors():
print(f"{name}: {predictor}")Test individual components
Break your pipeline into pieces and test each one:
class MyPipeline(dspy.Module):
def __init__(self):
self.step1 = dspy.ChainOfThought("question -> search_query")
self.step2 = dspy.Retrieve(k=3)
self.step3 = dspy.ChainOfThought("context, question -> answer")
def forward(self, question):
query = self.step1(question=question)
print(f"Step 1 output: {query.search_query}") # Debug
context = self.step2(query.search_query)
print(f"Step 2 retrieved: {len(context.passages)} passages") # Debug
answer = self.step3(context=context.passages, question=question)
print(f"Step 3 output: {answer.answer}") # Debug
return answerCompare prompts before/after optimization
# Before optimization
baseline = MyProgram()
baseline(question="test")
print("=== BASELINE PROMPT ===")
dspy.inspect_history(n=1)
# After optimization
optimized = MyProgram()
optimized.load("optimized.json")
optimized(question="test")
print("=== OPTIMIZED PROMPT ===")
dspy.inspect_history(n=1)Gotchas
- Jumping to code changes before reading `dspy.inspect_history()`. Claude tends to guess at fixes based on the error message alone. Always inspect the actual prompt and response first — the root cause is usually visible in the raw LM output (wrong format, truncated response, misunderstood instruction).
- Treating parse errors as LM problems when they are signature problems. When DSPy cannot parse the output, Claude often tries switching models or adding retry logic. The real fix is usually to simplify the output type, add field descriptions, or switch from
PredicttoChainOfThoughtso the model has space to reason before producing structured output. - Rewriting the whole program instead of isolating the broken component. Claude tends to refactor everything when one step fails. Test each predictor in the pipeline individually by calling it directly — the bug is typically in one specific step.
- Adding `try/except` around DSPy calls to swallow errors. This hides the real problem. DSPy errors (especially
ValueErrorfrom parsing) are diagnostic — they tell you exactly what the LM returned vs what was expected. Fix the root cause instead of catching and retrying. - Forgetting that optimized programs load stale demos. When a program worked before but breaks after changes, Claude often misses that
.load()restores old few-shot demos that no longer match the current signature. Re-optimize or clear the saved state after signature changes.
When NOT to use this skill
- No errors, just low accuracy — use
/ai-improving-accuracyinstead. This skill fixes crashes and parse failures, not quality problems. - Need to set up a new AI feature from scratch — use
/ai-doto get routed to the right building skill. This skill assumes you already have code that is broken. - Performance or cost issues without errors — use
/ai-cutting-costsor/ai-making-consistentdepending on the problem.
Cross-references
Install any skill: npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill <name>- Measure and improve accuracy after fixing errors — see
/ai-improving-accuracy - Trace a specific request end-to-end (every LM call, retrieval, latency) — see
/ai-tracing-requests - Monitor AI in production to catch errors early — see
/ai-monitoring - Understand DSPy modules (Predict, ChainOfThought, ReAct) — see
/dspy-modules - Iterative output refinement with feedback — see
/dspy-refine - Sample N outputs and pick the best — see
/dspy-best-of-n - Install `/ai-do` if you do not have it — it routes any AI problem to the right skill and is the fastest way to work:
npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill ai-do
Additional resources
- For complete error index, see reference.md
last_audit:
date: 2026-05-03
score: 45/45
versions:
dspy: 3.2.0
{
"skill_name": "ai-fixing-errors",
"evals": [
{
"id": 0,
"prompt": "I have a DSPy program that classifies support tickets. It was working fine last week but now I get 'ValueError: Could not parse output' on about half the inputs. I did not change any code. Using openai/gpt-4o-mini. Here is the signature:\n\nclass ClassifyTicket(dspy.Signature):\n ticket_text: str = dspy.InputField()\n category: Literal['billing', 'technical', 'account'] = dspy.OutputField()\n urgency: Literal['low', 'medium', 'high'] = dspy.OutputField()\n\nI optimized it with BootstrapFewShot and load from classify_ticket.json.",
"expected_output": "Debugging guidance that starts with inspecting dspy.inspect_history() to see what the LM is actually returning. Should consider that loaded demos from classify_ticket.json might be stale or that a model update changed output formatting. Should NOT immediately rewrite the signature or switch models.",
"files": [],
"assertions": [
{"name": "uses_inspect_history", "description": "Recommends dspy.inspect_history() to see the raw LM output before making changes"},
{"name": "checks_saved_state", "description": "Considers that loaded optimized state (classify_ticket.json) might contain stale demos"},
{"name": "does_not_rewrite_signature_first", "description": "Does not jump to rewriting the signature as the first fix — diagnoses first"},
{"name": "provider_agnostic_code", "description": "Any dspy.LM() calls include provider-alternative comments"},
{"name": "mentions_model_update_possibility", "description": "Notes that the model provider may have updated behavior since optimization"}
]
},
{
"id": 1,
"prompt": "My DSPy pipeline has 3 steps — generate search query, retrieve docs, then answer the question. It runs but the final answer is always wrong or generic. No errors in the console. I think the retriever is broken but not sure. How do I figure out what is going wrong?",
"expected_output": "Step-by-step isolation strategy: test each component individually, starting with inspect_history to see all 3 LM calls. Should show how to call each predictor separately and print intermediate outputs. Should NOT suggest rewriting the whole pipeline.",
"files": [],
"assertions": [
{"name": "isolates_components", "description": "Suggests testing each pipeline step individually rather than rewriting everything"},
{"name": "uses_inspect_history", "description": "Uses dspy.inspect_history() to examine what each step produced"},
{"name": "checks_retriever_directly", "description": "Shows how to test the retriever independently to verify it returns relevant passages"},
{"name": "prints_intermediate_outputs", "description": "Adds or suggests print statements between pipeline steps to see data flow"}
]
},
{
"id": 2,
"prompt": "I just set up DSPy for the first time. I'm trying to run a simple Predict call but I get AttributeError: 'NoneType' object has no attribute 'generate'. My code is:\n\nimport dspy\nclassify = dspy.Predict('text -> label')\nresult = classify(text='hello world')\n\nWhat am I doing wrong?",
"expected_output": "Identifies that dspy.configure(lm=...) was never called. Shows the fix with a provider-agnostic LM configuration. Should be concise since this is a simple setup issue.",
"files": [],
"assertions": [
{"name": "identifies_missing_configure", "description": "Correctly identifies that dspy.configure(lm=lm) is missing"},
{"name": "shows_fix_with_configure", "description": "Provides working code with dspy.configure() before the Predict call"},
{"name": "provider_agnostic_code", "description": "Any dspy.LM() calls include provider-alternative comments"},
{"name": "concise_response", "description": "Does not over-explain or suggest unnecessary changes beyond the missing configure call"}
]
}
]
}
Error Fixing Reference
Error Index
Setup Errors
| Error | Cause | Fix |
|---|---|---|
AttributeError: 'NoneType' on LM calls | LM not configured | dspy.configure(lm=dspy.LM("...")) |
AuthenticationError | Invalid API key | Check OPENAI_API_KEY or relevant env var |
ModuleNotFoundError: No module named 'dspy' | DSPy not installed | pip install -U dspy |
ImportError: cannot import name 'X' | Wrong DSPy version | pip install -U dspy to get latest |
Signature Errors
| Error | Cause | Fix |
|---|---|---|
TypeError: forward() got an unexpected keyword argument | Input field name mismatch | Match kwargs to InputField names |
ValueError: Could not parse output | LM output format mismatch | Check dspy.inspect_history(), simplify types |
ValidationError from Pydantic | Output doesn't match Pydantic model | Check type constraints, add field descriptions |
Output field is None | LM didn't produce that field | Add clearer field descriptions, use ChainOfThought |
Retriever Errors
| Error | Cause | Fix |
|---|---|---|
| Empty passages returned | Retriever not configured or returning no matches | Test retriever directly with a known query |
ConnectionError on retrieval | Retriever server down | Check server URL and connectivity |
| Wrong results retrieved | Bad query or wrong index | Test retriever directly, check index content |
Optimization Errors
| Error | Cause | Fix |
|---|---|---|
| Score drops after optimization | Overfitting or bad metric | Use validation set, check metric manually |
ValueError during compilation | Incompatible optimizer settings | Check optimizer requirements (data size, etc.) |
| Optimization takes too long | Too many trials or large data | Use auto="light", reduce trainset size |
FileNotFoundError on load | Wrong save path | Check the path passed to .save() |
Runtime Errors
| Error | Cause | Fix |
|---|---|---|
RateLimitError | Too many API calls | Add delays, reduce num_threads, use caching |
ContextLengthExceeded | Prompt too long | Reduce k in retriever, reduce few-shot demos |
dspy.Refine exhausts attempts | Output does not meet reward threshold | Lower threshold, make reward function return partial scores, increase N |
| Infinite loop in ReAct | Agent can't find answer | Set max_iters, check tool implementations |
Debugging Workflow
1. Does the AI respond?
+- No -> Check API key, model name, network
+- Yes v
2. Does the signature work standalone?
+- No -> Fix signature (types, descriptions, docstring)
+- Yes v
3. Does each module step work in isolation?
+- No -> Fix the failing step
+- Yes v
4. Does the full pipeline produce output?
+- No -> Check data flow between steps
+- Yes v
5. Is the output correct?
+- No -> Check with dspy.inspect_history(), optimize
+- Yes -> Done!Useful Debug Commands
# See what LM is configured
print(dspy.settings.lm)
# Test retriever directly (if using one)
# rm = dspy.ColBERTv2(url="http://..."); print(rm("test query", k=3))
# Inspect last N LM calls (prompts + responses)
dspy.inspect_history(n=3)
# Print module structure
print(my_program)
# List all predictors in a module
for name, pred in my_program.named_predictors():
print(f"{name}: {type(pred).__name__}")
# Test LM directly
lm = dspy.LM("openai/gpt-4o-mini")
print(lm("Say hello"))
# Check prediction fields
result = my_program(question="test")
print(result.keys()) # available fields
print(result) # all valuesPerformance Troubleshooting
Slow execution
- Reduce
num_threadsif hitting rate limits - Use a faster/cheaper LM for development
- Cache LM calls: DSPy caches by default, but check if cache is being used
High costs
- Use
gpt-4o-minior similar for development and optimization - Reduce training set size during optimization iteration
- Use
MIPROv2(auto="light")for quick optimization runs - See
/ai-cutting-costsfor systematic cost reduction
Inconsistent results
- Set
temperature=0for deterministic outputs:dspy.LM("...", temperature=0) - Run evaluation multiple times and average scores
- See
/ai-making-consistentfor systematic consistency improvement
Observability
Using DSPy's built-in tracing
# Enable tracing
dspy.configure(lm=lm, trace=[])
# After running, inspect trace
result = my_program(question="test")
# trace contains the execution pathLogging LM calls
import logging
logging.basicConfig(level=logging.DEBUG)
# Or selectively
logger = logging.getLogger("dspy")
logger.setLevel(logging.DEBUG)Counting LM calls and tokens
# Inspect recent LM calls
dspy.inspect_history(n=5)
# Or use lm.history to access raw call records