@yuaone/core 0.8.4 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -2
- package/dist/agent-loop.d.ts +8 -0
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +34 -0
- package/dist/agent-loop.js.map +1 -1
- package/dist/dag-orchestrator.d.ts +3 -0
- package/dist/dag-orchestrator.d.ts.map +1 -1
- package/dist/dag-orchestrator.js +1 -0
- package/dist/dag-orchestrator.js.map +1 -1
- package/dist/execution-engine.d.ts.map +1 -1
- package/dist/execution-engine.js +1 -0
- package/dist/execution-engine.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/language-detector.d.ts.map +1 -1
- package/dist/language-detector.js +43 -122
- package/dist/language-detector.js.map +1 -1
- package/dist/language-registry.d.ts +45 -0
- package/dist/language-registry.d.ts.map +1 -0
- package/dist/language-registry.js +893 -0
- package/dist/language-registry.js.map +1 -0
- package/dist/llm-client.d.ts +7 -0
- package/dist/llm-client.d.ts.map +1 -1
- package/dist/llm-client.js +58 -8
- package/dist/llm-client.js.map +1 -1
- package/dist/skill-loader.d.ts +9 -16
- package/dist/skill-loader.d.ts.map +1 -1
- package/dist/skill-loader.js +116 -52
- package/dist/skill-loader.js.map +1 -1
- package/dist/skill-mode-bridge.d.ts +17 -0
- package/dist/skill-mode-bridge.d.ts.map +1 -0
- package/dist/skill-mode-bridge.js +27 -0
- package/dist/skill-mode-bridge.js.map +1 -0
- package/dist/skills/code-review.md +58 -0
- package/dist/skills/debug.md +45 -0
- package/dist/skills/languages/python.md +89 -0
- package/dist/skills/languages/react.md +86 -0
- package/dist/skills/languages/typescript.md +110 -0
- package/dist/skills/plan.md +49 -0
- package/dist/skills/refactor.md +46 -0
- package/dist/skills/security-scan.md +59 -0
- package/dist/skills/skills/code-review.md +58 -0
- package/dist/skills/skills/debug.md +45 -0
- package/dist/skills/skills/languages/bash.md +74 -0
- package/dist/skills/skills/languages/c.md +76 -0
- package/dist/skills/skills/languages/cpp.md +75 -0
- package/dist/skills/skills/languages/csharp.md +77 -0
- package/dist/skills/skills/languages/cuda.md +80 -0
- package/dist/skills/skills/languages/dart.md +75 -0
- package/dist/skills/skills/languages/docker.md +80 -0
- package/dist/skills/skills/languages/elixir.md +80 -0
- package/dist/skills/skills/languages/gdscript.md +80 -0
- package/dist/skills/skills/languages/go.md +77 -0
- package/dist/skills/skills/languages/haskell.md +80 -0
- package/dist/skills/skills/languages/java.md +77 -0
- package/dist/skills/skills/languages/javascript.md +73 -0
- package/dist/skills/skills/languages/kotlin.md +75 -0
- package/dist/skills/skills/languages/lua.md +79 -0
- package/dist/skills/skills/languages/php.md +73 -0
- package/dist/skills/skills/languages/python.md +89 -0
- package/dist/skills/skills/languages/r.md +80 -0
- package/dist/skills/skills/languages/react.md +86 -0
- package/dist/skills/skills/languages/ruby.md +78 -0
- package/dist/skills/skills/languages/rust.md +77 -0
- package/dist/skills/skills/languages/solidity.md +81 -0
- package/dist/skills/skills/languages/sql.md +74 -0
- package/dist/skills/skills/languages/svelte.md +74 -0
- package/dist/skills/skills/languages/swift.md +74 -0
- package/dist/skills/skills/languages/terraform.md +80 -0
- package/dist/skills/skills/languages/typescript.md +110 -0
- package/dist/skills/skills/languages/verilog.md +80 -0
- package/dist/skills/skills/languages/vue.md +73 -0
- package/dist/skills/skills/plan.md +49 -0
- package/dist/skills/skills/refactor.md +46 -0
- package/dist/skills/skills/security-scan.md +59 -0
- package/dist/skills/skills/test-driven.md +51 -0
- package/dist/skills/test-driven.md +51 -0
- package/dist/strategy-selector.d.ts +11 -0
- package/dist/strategy-selector.d.ts.map +1 -0
- package/dist/strategy-selector.js +85 -0
- package/dist/strategy-selector.js.map +1 -0
- package/dist/sub-agent.d.ts +3 -0
- package/dist/sub-agent.d.ts.map +1 -1
- package/dist/sub-agent.js +10 -0
- package/dist/sub-agent.js.map +1 -1
- package/dist/system-prompt.d.ts +2 -0
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +469 -94
- package/dist/system-prompt.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: r
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.88
|
|
5
|
+
|
|
6
|
+
# R — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the exact error message and the call stack from `traceback()`. R errors are often generic ("object not found", "subscript out of bounds") but the call stack reveals which user function triggered the problem.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **"object 'x' not found"** — Variable not in scope or wrong environment.
|
|
12
|
+
- **"Error in ... : subscript out of bounds"** — Vector/list index out of range.
|
|
13
|
+
- **"Error in ... : incorrect number of dimensions"** — Subsetting a vector like a matrix.
|
|
14
|
+
- **"NAs introduced by coercion"** — `as.numeric()` or `as.integer()` on non-numeric strings.
|
|
15
|
+
- **"Error in ... : replacement has length zero"** — Empty vector assigned to subset.
|
|
16
|
+
- **"Warning: longer object length is not a multiple of shorter object length"** — Vector recycling mismatch.
|
|
17
|
+
- **"Error: could not find function '...'"** — Package not loaded; function name misspelled.
|
|
18
|
+
- **"there is no package called '...'"** — Package not installed.
|
|
19
|
+
|
|
20
|
+
## Known Error Patterns
|
|
21
|
+
|
|
22
|
+
### Object Not Found — Environment Scope
|
|
23
|
+
- **Symptom**: `Error in my_function() : object 'df' not found`; a variable that exists in the global environment is not accessible inside a function.
|
|
24
|
+
- **Cause**: R uses lexical scoping — functions look up variables in the environment where they were defined, not where they are called. A variable in the global environment is not automatically available inside a function that was defined in a different environment. Packages with `NSE` (non-standard evaluation) like `dplyr` use column names as symbols — passing a variable name as a string fails.
|
|
25
|
+
- **Strategy**: 1. Pass variables as function arguments rather than relying on global scope: `my_function(df = my_df)`. 2. For dplyr NSE, use `.data[[var_name]]` to reference columns programmatically: `df %>% mutate(new = .data[[col_name]])`. 3. Use `exists("varname")` to check before accessing. 4. Run `ls()` and `ls(envir = parent.env(environment()))` to inspect available names in current and parent environments. 5. Avoid `attach()` — it causes scope pollution and hard-to-track object-not-found errors.
|
|
26
|
+
- **Tool sequence**: file_read (function definition and call site) → file_edit (add explicit argument passing or .data[[]] notation)
|
|
27
|
+
- **Pitfall**: Do NOT use `<<-` (superassignment) to fix scope issues — it modifies the parent environment and causes state mutation bugs that are very hard to debug.
|
|
28
|
+
|
|
29
|
+
### Vector Recycling Surprise — Length Mismatch
|
|
30
|
+
- **Symptom**: `Warning: longer object length is not a multiple of shorter object length`; result vector has unexpected values; computation silently proceeds with wrong data.
|
|
31
|
+
- **Cause**: R recycles shorter vectors to match the length of longer ones in element-wise operations. `c(1,2,3,4) + c(10,20)` produces `c(11,22,13,24)` — the shorter vector is recycled. If lengths are not multiples, R issues a warning but still completes the operation.
|
|
32
|
+
- **Strategy**: 1. Treat the recycling warning as an error in data analysis code — check `length(x) == length(y)` before element-wise operations. 2. Use `stopifnot(length(x) == length(y))` as an assertion. 3. For intentional broadcasting of a scalar, document the intent explicitly. 4. In data frame operations, join data frames properly (merge/dplyr join) instead of relying on recycling. 5. Enable warnings as errors during development: `options(warn = 2)`.
|
|
33
|
+
- **Tool sequence**: file_read (arithmetic operations) → file_edit (add length checks or stopifnot assertions)
|
|
34
|
+
- **Pitfall**: Do NOT suppress the recycling warning with `suppressWarnings()` — the result is silently wrong. Fix the length mismatch.
|
|
35
|
+
|
|
36
|
+
### Factor vs Character Confusion — Unexpected Levels
|
|
37
|
+
- **Symptom**: String operations fail on what appears to be a character column; new values added to a factor become `NA`; `paste()` or `gsub()` produces unexpected output; `nlevels()` returns more levels than values present.
|
|
38
|
+
- **Cause**: Factors store categorical data as integers with level labels. When reading CSV files, `read.csv()` in older R versions (pre-4.0) converts string columns to factors by default. Treating a factor as a character vector causes type errors and unexpected behavior.
|
|
39
|
+
- **Strategy**: 1. Check column types: `str(df)` — factors show as `Factor w/ N levels`. 2. Convert when needed: `as.character(df$column)`. 3. In modern R (>=4.0), `read.csv` uses `stringsAsFactors = FALSE` by default. For older code, add this parameter explicitly. 4. Use `droplevels(df)` to remove unused factor levels after subsetting. 5. When comparing factor values, always compare to the level string: `df$col == "value"`, not `df$col == 1`.
|
|
40
|
+
- **Tool sequence**: shell_exec (`R -e "str(read.csv('file.csv'))"`) → file_read (data loading code) → file_edit (add stringsAsFactors=FALSE or explicit as.character())
|
|
41
|
+
- **Pitfall**: Do NOT convert factors to numeric with `as.numeric(factor_col)` — it gives the integer codes (1, 2, 3...), not the original values. Use `as.numeric(as.character(factor_col))`.
|
|
42
|
+
|
|
43
|
+
### NA Propagation — Silent Calculation Corruption
|
|
44
|
+
- **Symptom**: `mean(x)` returns `NA`; `sum(x) == NA`; a single missing value silently poisons an entire calculation.
|
|
45
|
+
- **Cause**: `NA` in R propagates through most arithmetic and logical operations — any operation involving `NA` returns `NA`. `mean(c(1, 2, NA, 4))` returns `NA` unless `na.rm = TRUE`.
|
|
46
|
+
- **Strategy**: 1. Always include `na.rm = TRUE` in aggregate functions when NA is acceptable: `mean(x, na.rm = TRUE)`, `sum(x, na.rm = TRUE)`. 2. Check for NAs explicitly: `any(is.na(x))` or `sum(is.na(x))`. 3. Decide on NA handling strategy upfront: drop rows (`na.omit(df)`), impute, or flag. 4. Use `complete.cases(df)` to subset to rows with no NAs. 5. For logical operations, `NA | TRUE == TRUE` but `NA & FALSE == FALSE` — be aware of three-valued logic.
|
|
47
|
+
- **Tool sequence**: grep (`mean(`, `sum(`, `max(`, `min(`) → file_read → file_edit (add na.rm = TRUE or explicit NA checks)
|
|
48
|
+
- **Pitfall**: Do NOT use `na.omit()` blindly on a data frame — it removes entire rows if any column has NA, which may discard more data than intended.
|
|
49
|
+
|
|
50
|
+
### Package Namespace Conflict — :: Required
|
|
51
|
+
- **Symptom**: `Warning: package 'dplyr' masks 'base' function 'filter'`; calling `filter()` calls the wrong function; behavior changes depending on load order of packages.
|
|
52
|
+
- **Cause**: Multiple packages export functions with the same name (e.g., `dplyr::filter` and `stats::filter`, `dplyr::lag` and `stats::lag`). The last loaded package wins the unqualified name. Load order affects which function is called.
|
|
53
|
+
- **Strategy**: 1. Use the `::` operator to explicitly namespace all function calls in production code: `dplyr::filter()`, `stats::filter()`. 2. Check for conflicts after loading packages: `conflicts()` lists all masked names. 3. Use the `conflicted` package which turns masking warnings into errors: `library(conflicted); conflict_prefer("filter", "dplyr")`. 4. At the top of scripts, document which packages are loaded and in what order.
|
|
54
|
+
- **Tool sequence**: shell_exec (`R -e "library(pkg); conflicts()"`) → file_read → file_edit (add :: namespace qualifiers to ambiguous calls)
|
|
55
|
+
- **Pitfall**: Do NOT rely on `library()` load order to resolve namespace conflicts — load order changes between environments and makes code non-reproducible.
|
|
56
|
+
|
|
57
|
+
### Memory Error — Copying Large Data Frames
|
|
58
|
+
- **Symptom**: `Error: cannot allocate vector of size N Gb`; R crashes or becomes very slow when processing large data frames; `gc()` doesn't help.
|
|
59
|
+
- **Cause**: R uses copy-on-modify semantics — modifying a column in a data frame creates a copy of the entire data frame. Repeated column additions in a loop (`df$new_col <- ...`) can trigger many copies. R also loads entire datasets into RAM.
|
|
60
|
+
- **Strategy**: 1. Use `data.table` for large datasets — it modifies by reference with `:=` operator, avoiding copies. 2. For loops that build data frames, use `lapply` + `do.call(rbind, list)` or `dplyr::bind_rows` instead of growing a data frame in a loop. 3. Use `fread()` from `data.table` for faster CSV loading with lower memory usage. 4. Process data in chunks for very large files. 5. Call `gc()` to force garbage collection after removing large objects with `rm(large_object)`.
|
|
61
|
+
- **Tool sequence**: file_read (data processing loops) → file_edit (replace loop with lapply/bind_rows or convert to data.table)
|
|
62
|
+
- **Pitfall**: Do NOT preallocate a data frame with empty rows and fill by index — it is slower than building a list and converting once at the end.
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
Run: `Rscript --vanilla your_script.R`
|
|
66
|
+
- No errors or warnings in output.
|
|
67
|
+
- Use `lintr::lint("script.R")` for style and potential bug checks.
|
|
68
|
+
- Run `testthat` tests: `devtools::test()` — all tests pass.
|
|
69
|
+
|
|
70
|
+
## Validation Checklist
|
|
71
|
+
- [ ] All functions receive data as arguments, not from global environment
|
|
72
|
+
- [ ] `na.rm = TRUE` specified in all aggregate functions where NA is possible
|
|
73
|
+
- [ ] No `stringsAsFactors = TRUE` in data loading (or explicit factor handling)
|
|
74
|
+
- [ ] Vector length equality checked before element-wise operations
|
|
75
|
+
- [ ] Recycling warnings treated as errors during development (`options(warn=2)`)
|
|
76
|
+
- [ ] All ambiguous function calls use `::` namespace qualifier
|
|
77
|
+
- [ ] `conflicted` package used or load order documented
|
|
78
|
+
- [ ] Large data frame operations use `data.table` or `dplyr` instead of loops
|
|
79
|
+
- [ ] `lintr` passes with no errors
|
|
80
|
+
- [ ] No use of `<<-` superassignment in package code
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: react
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.9
|
|
5
|
+
|
|
6
|
+
# React — Hook Rules, Rendering, and Common Errors
|
|
7
|
+
|
|
8
|
+
Read the full error message and component stack before touching any code.
|
|
9
|
+
|
|
10
|
+
## Hook Rules (Enforced by eslint-plugin-react-hooks)
|
|
11
|
+
- Call hooks only at the top level of a function component — never inside conditions, loops, or nested functions.
|
|
12
|
+
- Call hooks only from React function components or other custom hooks.
|
|
13
|
+
- Custom hooks must start with `use`.
|
|
14
|
+
- These rules are not style preferences — violating them causes non-deterministic behavior and crashes that are hard to reproduce.
|
|
15
|
+
|
|
16
|
+
## Known Error Patterns
|
|
17
|
+
|
|
18
|
+
### Hook Called Conditionally
|
|
19
|
+
- **Symptom**: ESLint error `React Hook "useX" is called conditionally` — or a runtime crash: `Rendered more hooks than during the previous render`
|
|
20
|
+
- **Cause**: Hook call placed inside an `if` block, after an early `return`, or inside a loop. React requires the same hooks to run in the same order on every render.
|
|
21
|
+
- **Strategy**: Move all hook calls to the top of the component function, above any conditional logic. If the hook should only do something conditionally, move the condition inside the hook's callback or pass a flag to the hook.
|
|
22
|
+
- **Tool sequence**: file_read (component) → file_edit (move hook calls above all conditionals)
|
|
23
|
+
- **Pitfall**: Do NOT wrap hook calls in try/catch or ternary expressions. Restructure the component so all hooks run unconditionally.
|
|
24
|
+
|
|
25
|
+
### Stale Closure in useEffect
|
|
26
|
+
- **Symptom**: Effect reads an old value of state or props. The callback always has the value from the first render regardless of updates.
|
|
27
|
+
- **Cause**: The dependency array is incomplete — it is missing variables that are read inside the effect.
|
|
28
|
+
- **Strategy**: Add every variable read inside the effect body to the dependency array. If adding a function reference creates an infinite loop, wrap the function in `useCallback` with its own deps. If adding an object creates an infinite loop, use `useMemo` or restructure to pass only primitive values.
|
|
29
|
+
- **Tool sequence**: file_read (useEffect block and deps array) → file_edit (add missing deps)
|
|
30
|
+
- **Pitfall**: Do NOT add `// eslint-disable-next-line react-hooks/exhaustive-deps` to suppress the exhaustive-deps warning. Fix the missing dependencies.
|
|
31
|
+
|
|
32
|
+
### Infinite Re-render Loop
|
|
33
|
+
- **Symptom**: Component re-renders continuously; browser tab becomes unresponsive or crashes.
|
|
34
|
+
- **Cause**: One of: (a) `setState` called unconditionally inside `useEffect` with no deps or with deps that always change, (b) an object or array literal created inline is in the dependency array (new reference every render), (c) parent passes a new object/function prop on every render.
|
|
35
|
+
- **Strategy**: 1. Read every `useEffect` in the component. Find any `setState` call without a guard condition. 2. Check the deps array for inline object/array literals — move them outside the component or wrap in `useMemo`/`useCallback`. 3. If the loop comes from a parent prop, memoize the prop at the parent.
|
|
36
|
+
- **Tool sequence**: file_read (all useEffect blocks) → file_edit (add condition or memoize deps)
|
|
37
|
+
- **Pitfall**: Do NOT add an empty dependency array `[]` to stop the loop without understanding why it loops. That causes stale closure bugs.
|
|
38
|
+
|
|
39
|
+
### Hydration Mismatch (Next.js / SSR)
|
|
40
|
+
- **Symptom**: `Error: Text content does not match server-rendered HTML` or `Error: Hydration failed because the initial UI does not match what was rendered on the server`
|
|
41
|
+
- **Cause**: Component renders different content on server vs. client. Common sources: `Date.now()`, `Math.random()`, `window` access, browser-only APIs, locale-dependent formatting.
|
|
42
|
+
- **Strategy**: 1. Identify the value that differs between server and client renders. 2. Move it into a `useEffect` with a local state variable — `useEffect` only runs on the client. 3. Render a placeholder or `null` on first render, then update after mount. 4. Use `suppressHydrationWarning` only on elements with genuinely intentional dynamic content such as timestamps.
|
|
43
|
+
- **Tool sequence**: file_read (component) → file_edit (move dynamic value to useEffect + useState)
|
|
44
|
+
- **Pitfall**: Do NOT use `suppressHydrationWarning` as a general fix. It hides real bugs where content genuinely differs.
|
|
45
|
+
|
|
46
|
+
### Missing key Prop in List
|
|
47
|
+
- **Symptom**: React warning `Each child in a list should have a unique "key" prop`
|
|
48
|
+
- **Cause**: `Array.map()` renders JSX elements without a `key` prop, or key is not unique within the list.
|
|
49
|
+
- **Strategy**: Add a stable, unique `key` to each element. Use the item's ID from data, not the array index.
|
|
50
|
+
- **Tool sequence**: grep (`\.map(`) → file_read (render section) → file_edit (add key prop)
|
|
51
|
+
- **Pitfall**: Do NOT use array index as key when the list can reorder, filter, or have items added or removed. Index keys cause incorrect reconciliation and state bugs.
|
|
52
|
+
|
|
53
|
+
### Cannot Read Property of Undefined (During Render)
|
|
54
|
+
- **Symptom**: `TypeError: Cannot read properties of undefined (reading 'x')` thrown during render
|
|
55
|
+
- **Cause**: Component accesses a property on a value that is `undefined` or `null` at mount time — typically async data, optional props, or uninitialized store state.
|
|
56
|
+
- **Strategy**: 1. Add a loading/null guard before the access: `if (!data) return null` or `data?.property`. 2. Provide a default value in the prop type or initial state. 3. Never assume async data is available at first render.
|
|
57
|
+
- **Tool sequence**: file_read (render return and prop types) → file_edit (add guard)
|
|
58
|
+
- **Pitfall**: Do NOT add `!` non-null assertion in TypeScript to hide this — the crash will still happen at runtime.
|
|
59
|
+
|
|
60
|
+
### Context Value Lost After Rerender
|
|
61
|
+
- **Symptom**: Component reads default context value instead of the provided value; context updates do not propagate.
|
|
62
|
+
- **Cause**: Provider is placed too low in the tree, or `value` prop creates a new object every render causing unnecessary re-renders and sometimes missed updates.
|
|
63
|
+
- **Strategy**: 1. Confirm the consuming component is inside the Provider in the tree. 2. Memoize the context value with `useMemo` to prevent new object reference on every render. 3. Split contexts if one high-frequency value is causing all consumers to re-render.
|
|
64
|
+
- **Tool sequence**: file_read (Provider placement) → file_read (consumer component) → file_edit (add useMemo to context value)
|
|
65
|
+
- **Pitfall**: Do NOT create the context value inline in the JSX without memoization — `value={{ foo, bar }}` creates a new object on every render.
|
|
66
|
+
|
|
67
|
+
### useRef Value Not Triggering Re-render
|
|
68
|
+
- **Symptom**: Component does not update when a `ref.current` value changes.
|
|
69
|
+
- **Cause**: `useRef` mutations do not trigger re-renders — this is by design.
|
|
70
|
+
- **Strategy**: If you need UI to update when a value changes, use `useState` or `useReducer` instead. Use `useRef` only for values that should NOT trigger re-renders: DOM references, timers, previous value tracking, and imperative handles.
|
|
71
|
+
- **Tool sequence**: file_read (ref usage) → file_edit (convert to useState if re-render is needed)
|
|
72
|
+
- **Pitfall**: Do NOT try to force a re-render after mutating a ref. Switch to state.
|
|
73
|
+
|
|
74
|
+
## Verification
|
|
75
|
+
- ESLint: `eslint --ext .tsx,.ts src/` — look for `react-hooks/rules-of-hooks` and `react-hooks/exhaustive-deps` violations.
|
|
76
|
+
- Type check: `tsc --noEmit`
|
|
77
|
+
- Dev server: confirm no console errors beginning with `Warning: ` or `Error: ` in the browser.
|
|
78
|
+
|
|
79
|
+
## Validation Checklist
|
|
80
|
+
- [ ] All hooks called unconditionally at component top level, before any early returns
|
|
81
|
+
- [ ] useEffect dependency arrays include all referenced variables (no exhaustive-deps suppressions)
|
|
82
|
+
- [ ] No inline object or array literals in dependency arrays
|
|
83
|
+
- [ ] All list renders have stable unique keys from data (not array index)
|
|
84
|
+
- [ ] Browser-only code wrapped in useEffect or guarded with `typeof window !== "undefined"`
|
|
85
|
+
- [ ] Context values memoized with useMemo if they are object or array literals
|
|
86
|
+
- [ ] Async data access guarded with null/undefined check at render time
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: ruby
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.92
|
|
5
|
+
|
|
6
|
+
# Ruby — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the full backtrace before acting. Ruby exceptions include the class, message, and call stack — all three matter.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **NoMethodError** — Called a method on nil or wrong object type.
|
|
12
|
+
- **LoadError** — require path not found; gem not installed or path wrong.
|
|
13
|
+
- **ArgumentError** — Wrong number of arguments or invalid argument value.
|
|
14
|
+
- **NameError** — Uninitialized constant; missing require or wrong namespace.
|
|
15
|
+
- **TypeError** — Operation applied to wrong type (e.g., nil coercion).
|
|
16
|
+
- **Encoding::UndefinedConversionError** — Encoding incompatibility during string conversion.
|
|
17
|
+
- **RuntimeError** — Generic raise without a specific exception class.
|
|
18
|
+
- **ZeroDivisionError** — Division by zero.
|
|
19
|
+
- **KeyError** — fetch on a Hash with a missing key and no default.
|
|
20
|
+
- **Errno::ENOENT** — File not found on disk.
|
|
21
|
+
|
|
22
|
+
## Known Error Patterns
|
|
23
|
+
|
|
24
|
+
### NoMethodError: undefined method for nil
|
|
25
|
+
- **Symptom**: `NoMethodError: undefined method 'foo' for nil:NilClass`
|
|
26
|
+
- **Cause**: A method is called on a variable that is nil. Common after a failed `find`, `first`, optional chain that returns nil, or a hash lookup with a missing key.
|
|
27
|
+
- **Strategy**: 1. Read the backtrace line to identify the variable. 2. Trace where the variable is assigned — grep the variable name and read assignments. 3. Add a nil guard: `return unless obj`, `obj&.method`, or raise a more descriptive error if nil is illegal at that point.
|
|
28
|
+
- **Tool sequence**: grep (variable assignment) → file_read (surrounding block) → file_edit (add nil guard)
|
|
29
|
+
- **Pitfall**: Do NOT add `.to_s` or similar to silence the error. Determine why nil is reaching that line.
|
|
30
|
+
|
|
31
|
+
### LoadError: cannot load such file
|
|
32
|
+
- **Symptom**: `LoadError: cannot load such file -- some/path`
|
|
33
|
+
- **Cause**: `require` or `require_relative` path is wrong, the gem is not in the Gemfile, or the gem is not installed.
|
|
34
|
+
- **Strategy**: 1. Check if the path is a gem name — grep Gemfile for the name. 2. If missing, add it with `bundle add <gem>`. 3. If it is a relative path, verify the file exists using shell_exec. 4. Check the load path with `$LOAD_PATH` in a debug session if the gem is installed but not found.
|
|
35
|
+
- **Tool sequence**: grep (Gemfile) → shell_exec (`ls` on path) → file_edit (Gemfile or require statement)
|
|
36
|
+
- **Pitfall**: Do NOT assume the gem is installed. Always check Gemfile.lock for the actual resolved gem list.
|
|
37
|
+
|
|
38
|
+
### ArgumentError: wrong number of arguments
|
|
39
|
+
- **Symptom**: `ArgumentError: wrong number of arguments (given N, expected M)`
|
|
40
|
+
- **Cause**: Calling a method with more or fewer arguments than defined. Common after refactoring method signatures.
|
|
41
|
+
- **Strategy**: 1. Read the method definition (grep the method name). 2. Count required, optional (`= default`), and splat (`*args`) parameters. 3. Fix the call site to match the signature. If the definition is wrong, update it and check all call sites.
|
|
42
|
+
- **Tool sequence**: grep (method name `def `) → file_read (definition) → grep (call sites) → file_edit
|
|
43
|
+
- **Pitfall**: Do NOT add default values to all parameters just to silence the error — required parameters are required for a reason.
|
|
44
|
+
|
|
45
|
+
### NameError: uninitialized constant
|
|
46
|
+
- **Symptom**: `NameError: uninitialized constant Foo::Bar`
|
|
47
|
+
- **Cause**: A class or module constant is referenced but not loaded. Missing require, wrong namespace, or autoloading not configured.
|
|
48
|
+
- **Strategy**: 1. Search for the class definition (grep `class Bar` or `module Bar`). 2. Check if the file is required or autoloaded. In Rails, verify the file is in an autoloaded directory. Outside Rails, add `require_relative` or `require`. 3. Check the namespace — `Foo::Bar` means `Bar` must be defined inside `module Foo`.
|
|
49
|
+
- **Tool sequence**: grep (`class Bar\|module Bar`) → file_read (top of failing file) → file_edit (add require or fix namespace)
|
|
50
|
+
- **Pitfall**: Do NOT add a `rescue NameError` to suppress this. Find and load the correct constant.
|
|
51
|
+
|
|
52
|
+
### Encoding::UndefinedConversionError
|
|
53
|
+
- **Symptom**: `Encoding::UndefinedConversionError: "\xXX" from ASCII-8BIT to UTF-8`
|
|
54
|
+
- **Cause**: A string with one encoding is being converted to an incompatible encoding. Common when reading binary files, external HTTP responses, or database fields without encoding declared.
|
|
55
|
+
- **Strategy**: 1. Identify the source of the problematic string (file read, HTTP body, DB field). 2. Set the correct source encoding: `string.force_encoding('UTF-8')` if you know the source is UTF-8. 3. Use `encode` with error handling: `string.encode('UTF-8', invalid: :replace, undef: :replace)` for lossy conversion if the data may be dirty. 4. For file reads, pass `encoding: 'UTF-8'` to `File.read`.
|
|
56
|
+
- **Tool sequence**: file_read (string source) → file_edit (add encoding declaration or encode call)
|
|
57
|
+
- **Pitfall**: Do NOT use `force_encoding` blindly — it only relabels the encoding without converting. Use `encode` when actual conversion is needed.
|
|
58
|
+
|
|
59
|
+
### Frozen String Modification
|
|
60
|
+
- **Symptom**: `FrozenError: can't modify frozen String` (or `RuntimeError` in older Ruby)
|
|
61
|
+
- **Cause**: Attempting to mutate a frozen string. Common with `# frozen_string_literal: true` magic comment, string literals from constants, or strings returned from certain gem methods.
|
|
62
|
+
- **Strategy**: 1. Read the line causing the error. 2. If using `<<`, `gsub!`, `sub!`, or direct index assignment, replace with the non-bang version and reassign: `str = str.gsub(...)`. 3. If mutation is intentional, use `str = str.dup` before mutating.
|
|
63
|
+
- **Tool sequence**: file_read (error line) → file_edit (replace mutating call with non-mutating + reassign)
|
|
64
|
+
- **Pitfall**: Do NOT remove the `# frozen_string_literal: true` comment. Fix the mutation instead.
|
|
65
|
+
|
|
66
|
+
## Verification
|
|
67
|
+
Run: `ruby -c <file>` for syntax check, `bundle exec ruby <file>` for runtime.
|
|
68
|
+
- For Rails: `bundle exec rails runner <file>` or run the test suite.
|
|
69
|
+
- Always run with `bundle exec` to use the Gemfile-resolved gem versions.
|
|
70
|
+
|
|
71
|
+
## Validation Checklist
|
|
72
|
+
- [ ] No `rescue Exception` without re-raising or explicit justification (catches signals)
|
|
73
|
+
- [ ] All `require` paths verified to exist or gem present in Gemfile
|
|
74
|
+
- [ ] nil guard added wherever a method result could be nil
|
|
75
|
+
- [ ] No `.freeze` removed to fix FrozenError — fix the mutation instead
|
|
76
|
+
- [ ] Encoding specified at string source, not just at the point of failure
|
|
77
|
+
- [ ] `bundle exec` used for all ruby/rake/rails invocations
|
|
78
|
+
- [ ] Method signatures verified at all call sites after any definition change
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: rust
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.95
|
|
5
|
+
|
|
6
|
+
# Rust — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the full `rustc` error output including the `help:` and `note:` lines. Rust's compiler diagnostics are among the most detailed available — the suggestion often contains the exact fix.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **E0502** — Cannot borrow as mutable because it is also borrowed as immutable.
|
|
12
|
+
- **E0505** — Cannot move out of value because it is borrowed.
|
|
13
|
+
- **E0507** — Cannot move out of `*x` which is behind a reference.
|
|
14
|
+
- **E0106** — Missing lifetime specifier.
|
|
15
|
+
- **E0277** — Trait bound not satisfied.
|
|
16
|
+
- **E0308** — Mismatched types.
|
|
17
|
+
- **E0004** — Non-exhaustive patterns in match.
|
|
18
|
+
- **E0382** — Use of moved value.
|
|
19
|
+
- **E0499** — Cannot borrow as mutable more than once at a time.
|
|
20
|
+
- **E0716** — Temporary value dropped while borrowed.
|
|
21
|
+
|
|
22
|
+
## Known Error Patterns
|
|
23
|
+
|
|
24
|
+
### Pattern: borrow checker — cannot borrow as mutable (E0502 / E0499)
|
|
25
|
+
|
|
26
|
+
- **symptom**: `cannot borrow 'x' as mutable because it is also borrowed as immutable` or `cannot borrow 'x' as mutable more than once at a time`
|
|
27
|
+
- **cause**: Rust enforces at most one mutable reference OR any number of immutable references at a time. Violating this at the same scope triggers E0502/E0499.
|
|
28
|
+
- **strategy**: 1. Read the error span — it shows exactly where each borrow starts and ends. 2. Restructure code so the immutable borrow is dropped (goes out of scope or is no longer used) before the mutable borrow begins. 3. If both borrows are needed simultaneously, clone the data for the immutable side. 4. For collections, use `split_at_mut` or index-based access instead of simultaneous slice references.
|
|
29
|
+
- **toolSequence**: file_read (error lines) → file_edit (restructure borrow scopes or add `.clone()`)
|
|
30
|
+
- **pitfall**: Do NOT reach for `unsafe` or `RefCell` as the first solution. Restructuring lifetimes or cloning is almost always the correct fix.
|
|
31
|
+
|
|
32
|
+
### Pattern: lifetime annotation error (E0106 / E0597)
|
|
33
|
+
|
|
34
|
+
- **symptom**: `missing lifetime specifier` or `borrowed value does not live long enough` — value dropped while still borrowed
|
|
35
|
+
- **cause**: A reference in a struct, function return, or trait object lacks a lifetime annotation, or a local variable is returned as a reference but is dropped at end of function.
|
|
36
|
+
- **strategy**: 1. Read the error to find where the lifetime is needed. 2. For struct fields holding references, add a lifetime parameter to the struct: `struct Foo<'a> { x: &'a str }`. 3. For function returns borrowing from input, add matching lifetime: `fn foo<'a>(x: &'a str) -> &'a str`. 4. If returning a reference to a local, return an owned value (`String`, `Vec`, etc.) instead. 5. Use `'static` only for string literals or `Box::leak` — never to silence the error.
|
|
37
|
+
- **toolSequence**: file_read (struct or function definition) → file_edit (add lifetime parameters)
|
|
38
|
+
- **pitfall**: Do NOT add `'static` to every lifetime just to make the compiler happy — it severely restricts callers and is almost always wrong.
|
|
39
|
+
|
|
40
|
+
### Pattern: match non-exhaustive (E0004)
|
|
41
|
+
|
|
42
|
+
- **symptom**: `non-exhaustive patterns: X not covered` in a `match` expression
|
|
43
|
+
- **cause**: The match does not cover all variants of an enum, or a range/literal pattern leaves some values unhandled.
|
|
44
|
+
- **strategy**: 1. Read the error to find the uncovered variant(s). 2. Add an explicit arm for each missing variant. 3. If a catch-all is semantically correct, add `_ => { /* handle default */ }` at the end. 4. For enums you own, prefer explicit arms over `_` so new variants added later cause compile errors.
|
|
45
|
+
- **toolSequence**: file_read (enum definition) → file_read (match expression) → file_edit (add missing arms)
|
|
46
|
+
- **pitfall**: Do NOT add `_ => unreachable!()` unless you have formally proven the branch cannot be reached — prefer `_ => panic!("unexpected variant: {:?}", x)` for better diagnostics.
|
|
47
|
+
|
|
48
|
+
### Pattern: unwrap on None/Err (runtime panic)
|
|
49
|
+
|
|
50
|
+
- **symptom**: `thread 'main' panicked at 'called Option::unwrap() on a None value'` or `called Result::unwrap() on an Err value`
|
|
51
|
+
- **cause**: `.unwrap()` or `.expect()` on an `Option` or `Result` that is `None`/`Err` at runtime. Often from file I/O, parsing, or indexing.
|
|
52
|
+
- **strategy**: 1. Locate every `.unwrap()` and `.expect()` in the code path that panicked. 2. Replace with proper error propagation using `?` operator or explicit match. 3. For `Option`, use `.unwrap_or(default)`, `.unwrap_or_else(|| compute())`, or `if let Some(x) = opt { ... }`. 4. For `Result`, propagate with `?` in functions that return `Result`, or handle with `match`/`if let Err(e)`.
|
|
53
|
+
- **toolSequence**: grep (`\.unwrap()\|\.expect(`) → file_read (each occurrence) → file_edit (replace with `?` or match)
|
|
54
|
+
- **pitfall**: Do NOT replace `.unwrap()` with `.unwrap_or_default()` blindly — the default value (empty string, 0, false) may silently cause incorrect behavior downstream.
|
|
55
|
+
|
|
56
|
+
### Pattern: trait not implemented for type (E0277)
|
|
57
|
+
|
|
58
|
+
- **symptom**: `the trait bound 'MyType: SomeTrait' is not satisfied` or `'MyType' doesn't implement 'Display'`
|
|
59
|
+
- **cause**: A generic function, operator, or macro requires a trait that the concrete type does not implement. Common cases: `Display`, `Debug`, `Clone`, `Send`, `Sync`, `Iterator`.
|
|
60
|
+
- **strategy**: 1. Read the full error including `note:` lines — they list which trait is required and where. 2. For `Debug`/`Clone`/`PartialEq`, add `#[derive(Debug, Clone, PartialEq)]` to the struct. 3. For custom traits, implement them manually. 4. For `Send`/`Sync`, check if the type contains non-Send/Sync fields (like `Rc`, raw pointers) and replace with thread-safe alternatives (`Arc`). 5. For third-party types, use a newtype wrapper to implement the trait.
|
|
61
|
+
- **toolSequence**: file_read (type definition) → file_edit (add `#[derive(...)]` or `impl Trait for Type`)
|
|
62
|
+
- **pitfall**: Do NOT implement `unsafe impl Send for T` to silence the error — this can cause data races. Fix the underlying non-Send field instead.
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
Run: `cargo check` and `cargo clippy -- -D warnings`
|
|
66
|
+
- `cargo check` exit 0 = no compile errors (faster than `cargo build`).
|
|
67
|
+
- `cargo clippy` with `-D warnings` = no lints that could become bugs.
|
|
68
|
+
- For tests: `cargo test`
|
|
69
|
+
|
|
70
|
+
## Validation Checklist
|
|
71
|
+
- [ ] `cargo check` exits 0 with no errors
|
|
72
|
+
- [ ] `cargo clippy -- -D warnings` exits 0
|
|
73
|
+
- [ ] No `.unwrap()` in production code paths without comment explaining the guarantee
|
|
74
|
+
- [ ] Every `context.WithCancel` equivalent (Drop impl) verified to run on all paths
|
|
75
|
+
- [ ] Lifetime annotations are minimal — not `'static` unless truly static
|
|
76
|
+
- [ ] Non-exhaustive match arms handled explicitly, not silently with `_`
|
|
77
|
+
- [ ] `unsafe` blocks, if any, have a `// SAFETY:` comment explaining the invariant
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: solidity
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.95
|
|
5
|
+
|
|
6
|
+
# Solidity — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the exact compiler error and line number first. Solidity errors often point to a security vulnerability, not just a type mismatch — treat every warning as a potential exploit vector.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **SWC-107** — Reentrancy: external call before state update.
|
|
12
|
+
- **SWC-101** — Integer overflow/underflow (pre-0.8.x without SafeMath).
|
|
13
|
+
- **SWC-104** — Unchecked return value from low-level call.
|
|
14
|
+
- **SWC-115** — tx.origin used for authentication.
|
|
15
|
+
- **SWC-128** — DoS with failed call (gas exhaustion).
|
|
16
|
+
- **TypeError: Overriding function missing "override"** — function override not declared.
|
|
17
|
+
- **TypeError: Function state mutability can be restricted** — view/pure missing.
|
|
18
|
+
- **Warning: Return value of low-level call is not used** — unchecked `.call()` return.
|
|
19
|
+
- **DeclarationError: Identifier already declared** — name collision in scope.
|
|
20
|
+
|
|
21
|
+
## Known Error Patterns
|
|
22
|
+
|
|
23
|
+
### Reentrancy Attack — Call Before State Update
|
|
24
|
+
- **Symptom**: Funds drained repeatedly in a single transaction; contract balance zeroed unexpectedly. Compiler may emit no error — this is a logic bug.
|
|
25
|
+
- **Cause**: An external `.call{value: amount}()` is made before the internal accounting state (balance mapping, flag) is updated. The callee's `receive()` or `fallback()` re-enters the function before the state reflects the first withdrawal.
|
|
26
|
+
- **Strategy**: 1. Grep all external calls (`\.call{`, `\.transfer(`, `\.send(`). 2. For each call site, read the function and verify the state update (e.g., `balances[msg.sender] -= amount`) happens BEFORE the call. 3. Apply the Checks-Effects-Interactions (CEI) pattern: checks first, state mutations second, external interactions last. 4. As an additional layer, add a `ReentrancyGuard` modifier using a `locked` boolean flag. 5. Re-audit any function that calls an external contract.
|
|
27
|
+
- **Tool sequence**: grep (`\.call{value`) → file_read → file_edit (move state update before call, add nonReentrant modifier)
|
|
28
|
+
- **Pitfall**: Do NOT rely on `transfer()` or `send()` alone as reentrancy protection — their 2300 gas stipend is not guaranteed to remain safe with EVM upgrades (EIP-1884).
|
|
29
|
+
|
|
30
|
+
### Integer Overflow / Underflow — Pre-0.8.x SafeMath
|
|
31
|
+
- **Symptom**: Token balances wrap around to huge values; subtraction from small value produces near-`uint256` max.
|
|
32
|
+
- **Cause**: Solidity <0.8.0 does not revert on arithmetic overflow/underflow. `uint8(255) + 1 == 0`. Without SafeMath, any unchecked arithmetic can wrap.
|
|
33
|
+
- **Strategy**: 1. Check the `pragma solidity` version at the top of each file. 2. If <0.8.0, grep all arithmetic operations (`+`, `-`, `*`, `/`) on numeric types. 3. Import and use OpenZeppelin's SafeMath library for every operation, or upgrade to >=0.8.0 which has built-in overflow checks. 4. After upgrade, test edge cases (max value +1, 0 -1) in unit tests.
|
|
34
|
+
- **Tool sequence**: grep (`pragma solidity`) → file_read (arithmetic operations) → file_edit (add SafeMath or upgrade pragma)
|
|
35
|
+
- **Pitfall**: Do NOT assume `uint256` is safe from underflow — subtracting from a value smaller than the subtrahend wraps to near `2^256`. Underflow is as dangerous as overflow.
|
|
36
|
+
|
|
37
|
+
### Unchecked Return Value — ERC20 transfer / low-level call
|
|
38
|
+
- **Symptom**: Transfer silently fails; funds are not moved but execution continues. Non-reverting ERC20 tokens (e.g., USDT) return `false` instead of reverting.
|
|
39
|
+
- **Cause**: `token.transfer(to, amount)` on non-standard ERC20 tokens returns `false` on failure instead of reverting. Low-level `.call()` always returns `(bool success, bytes memory data)` — ignoring `success` means silent failures.
|
|
40
|
+
- **Strategy**: 1. Grep all `.transfer(`, `.transferFrom(`, `.call(` usages. 2. For ERC20 transfers, use OpenZeppelin's `SafeERC20.safeTransfer()` which internally checks return values and reverts on failure. 3. For low-level calls, always destructure and check: `(bool success, ) = addr.call{...}(...); require(success, "call failed");`. 4. Audit all external call return values.
|
|
41
|
+
- **Tool sequence**: grep (`\.call(`, `\.transfer(`) → file_read → file_edit (wrap with SafeERC20 or add require(success))
|
|
42
|
+
- **Pitfall**: Do NOT use `.transfer()` on ERC20 tokens and assume it behaves like ETH transfer — they are completely different methods.
|
|
43
|
+
|
|
44
|
+
### tx.origin Authentication Bypass
|
|
45
|
+
- **Symptom**: Phishing contract can call victim contract on behalf of the original signer; access control is bypassed.
|
|
46
|
+
- **Cause**: `tx.origin` refers to the original EOA that initiated the entire transaction chain, not the immediate caller. A malicious contract in the call chain can exploit `require(tx.origin == owner)` because `tx.origin` is the user, not the attacker contract.
|
|
47
|
+
- **Strategy**: 1. Grep all occurrences of `tx.origin`. 2. Replace every access control check with `msg.sender` — the immediate caller. 3. Only use `tx.origin` if you explicitly need to differentiate EOA from contract (e.g., `require(tx.origin == msg.sender, "no contracts")`) — but even this is rarely correct.
|
|
48
|
+
- **Tool sequence**: grep (`tx\.origin`) → file_read → file_edit (replace with msg.sender)
|
|
49
|
+
- **Pitfall**: Do NOT use `tx.origin == msg.sender` as a "contracts not allowed" guard in production — wallets like Gnosis Safe are themselves contracts and will be blocked.
|
|
50
|
+
|
|
51
|
+
### Gas Estimation Failure — Out-of-Gas in Loop
|
|
52
|
+
- **Symptom**: Transaction reverts with `out of gas`; Hardhat/Foundry estimates wildly differ from actual gas. Loops over dynamic arrays cause this.
|
|
53
|
+
- **Cause**: Iterating over an unbounded array (e.g., `for (uint i = 0; i < users.length; i++)`) consumes gas proportional to array size. If the array grows large enough, the gas cost exceeds the block gas limit, permanently locking the function.
|
|
54
|
+
- **Strategy**: 1. Grep all `for` loops and `while` loops in contracts. 2. Identify loops over storage arrays that are user-controlled or unbounded. 3. Replace unbounded loops with a pull-payment pattern (each user claims individually) or pagination (process N items per call). 4. Use events for off-chain aggregation instead of on-chain loops. 5. Set a max iteration constant if the loop must exist.
|
|
55
|
+
- **Tool sequence**: grep (`for (`, `while (`) → file_read → file_edit (add max cap or extract to pull pattern)
|
|
56
|
+
- **Pitfall**: Do NOT add a `gasleft() > MINIMUM` check as the primary fix — it converts a revert into a partial execution, which is often worse.
|
|
57
|
+
|
|
58
|
+
### Visibility Not Specified — Default Public
|
|
59
|
+
- **Symptom**: Sensitive function callable by anyone; Slither warns "function has no visibility specifier."
|
|
60
|
+
- **Cause**: Solidity <0.5.0 defaulted functions to `public` when no visibility was specified. In >=0.5.0 this is a compile error, but audits of legacy code reveal functions that should be `internal` or `private`.
|
|
61
|
+
- **Strategy**: 1. Grep all `function` declarations. 2. Verify each has an explicit `public`, `external`, `internal`, or `private` specifier. 3. Apply principle of least privilege: prefer `internal` for helper functions, `external` for functions only called from outside. 4. Run Slither static analysis to catch visibility issues automatically.
|
|
62
|
+
- **Tool sequence**: grep (`function `) → file_read → file_edit (add explicit visibility)
|
|
63
|
+
- **Pitfall**: Do NOT blindly mark all functions `private` — internal contract helpers called by child contracts must be `internal`.
|
|
64
|
+
|
|
65
|
+
## Verification
|
|
66
|
+
Run: `solc --strict-assembly` or `npx hardhat compile`
|
|
67
|
+
- Zero errors and zero warnings (especially SWC warnings) = passing baseline.
|
|
68
|
+
- Run Slither: `slither . --print human-summary` for static analysis.
|
|
69
|
+
- Run Foundry tests: `forge test -vvv` — all tests must pass.
|
|
70
|
+
|
|
71
|
+
## Validation Checklist
|
|
72
|
+
- [ ] All arithmetic uses SafeMath or pragma >=0.8.0 with no `unchecked` blocks near user input
|
|
73
|
+
- [ ] No `tx.origin` used for access control
|
|
74
|
+
- [ ] Every `.call()` return value is checked with `require(success, ...)`
|
|
75
|
+
- [ ] CEI pattern enforced: state updates happen before all external calls
|
|
76
|
+
- [ ] No unbounded loops over user-controlled storage arrays
|
|
77
|
+
- [ ] All functions have explicit visibility specifiers
|
|
78
|
+
- [ ] Reentrancy guard applied to all state-changing functions that make external calls
|
|
79
|
+
- [ ] ERC20 interactions use SafeERC20 wrappers
|
|
80
|
+
- [ ] Events emitted for all state changes (for off-chain auditability)
|
|
81
|
+
- [ ] Slither static analysis passes with no high-severity findings
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: sql
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.91
|
|
5
|
+
|
|
6
|
+
# SQL — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the query plan (`EXPLAIN ANALYZE`) before optimizing. Most SQL performance bugs are visible in the plan. Always check the execution count and actual rows vs. estimated rows.
|
|
9
|
+
|
|
10
|
+
## Quick Reference
|
|
11
|
+
- **Seq Scan** — Full table scan; usually means missing or unused index.
|
|
12
|
+
- **Nested Loop** — Can be N+1 if the inner query is driven by outer rows without batching.
|
|
13
|
+
- **Hash Join / Merge Join** — Efficient for large set joins.
|
|
14
|
+
- **Filter** — Rows filtered AFTER scan; ideally filters happen at index scan level.
|
|
15
|
+
- **NULL** — Not equal to anything, including itself. Use `IS NULL` / `IS NOT NULL`.
|
|
16
|
+
|
|
17
|
+
## Known Error Patterns
|
|
18
|
+
|
|
19
|
+
### N+1 Query — Missing JOIN
|
|
20
|
+
- **Symptom**: Application issues one query to fetch N parent rows, then N separate queries to fetch child data. Slow page loads proportional to result set size.
|
|
21
|
+
- **Cause**: ORM lazy loading or application-level loop issuing per-row queries. The database work is done outside SQL.
|
|
22
|
+
- **Strategy**: 1. Log all queries during a request (ORM query log or `pg_stat_statements`). 2. Identify repeated queries differing only by an ID parameter. 3. Rewrite as a single query using JOIN or a subquery: `SELECT p.*, c.* FROM parents p JOIN children c ON c.parent_id = p.id WHERE p.id IN (...)`. 4. In ORMs, use eager loading: `.includes()`, `.eager_load()`, `JOIN FETCH`, etc.
|
|
23
|
+
- **Tool sequence**: shell_exec (query log or EXPLAIN) → file_read (ORM query code) → file_edit (add JOIN or eager load)
|
|
24
|
+
- **Pitfall**: Do NOT add `LIMIT 1` to inner queries as a workaround — batch the entire fetch in one query.
|
|
25
|
+
|
|
26
|
+
### Index Not Used — Function on Indexed Column
|
|
27
|
+
- **Symptom**: `EXPLAIN ANALYZE` shows Seq Scan on a large table even though an index exists on the column in the WHERE clause.
|
|
28
|
+
- **Cause**: Wrapping an indexed column in a function (`WHERE LOWER(email) = ...`, `WHERE DATE(created_at) = ...`) prevents the index from being used because the index stores the raw value, not the function result.
|
|
29
|
+
- **Strategy**: 1. Run `EXPLAIN ANALYZE` on the slow query. 2. Identify the Seq Scan and the WHERE predicate. 3. Options: a) Create a functional index: `CREATE INDEX ON users (LOWER(email));`. b) Rewrite the query to avoid the function on the column side: `WHERE created_at >= '2024-01-01' AND created_at < '2024-01-02'` instead of `WHERE DATE(created_at) = '2024-01-01'`. c) Store the normalized value in a separate indexed column.
|
|
30
|
+
- **Tool sequence**: shell_exec (`EXPLAIN ANALYZE <query>`) → file_read (query definition) → file_edit (rewrite predicate or add functional index)
|
|
31
|
+
- **Pitfall**: Do NOT add an index to the column if the query wraps it in a function. The new index will also be unused.
|
|
32
|
+
|
|
33
|
+
### NULL Comparison — IS NULL vs = NULL
|
|
34
|
+
- **Symptom**: `WHERE column = NULL` returns zero rows even when null values exist. `WHERE column != NULL` also returns zero rows.
|
|
35
|
+
- **Cause**: In SQL, NULL represents an unknown value. Any comparison with `=`, `!=`, `<`, `>` against NULL evaluates to NULL (unknown), not TRUE or FALSE. Rows are only returned where the predicate is TRUE.
|
|
36
|
+
- **Strategy**: 1. Replace `= NULL` with `IS NULL`. 2. Replace `!= NULL` or `<> NULL` with `IS NOT NULL`. 3. For COALESCE or conditional logic: `COALESCE(column, default_value)`.
|
|
37
|
+
- **Tool sequence**: grep (`= NULL\|!= NULL\|<> NULL`) → file_read → file_edit (replace with IS NULL / IS NOT NULL)
|
|
38
|
+
- **Pitfall**: `NOT IN (subquery)` silently returns zero rows if the subquery contains any NULL values. Use `NOT EXISTS` instead for nullable subqueries.
|
|
39
|
+
|
|
40
|
+
### Implicit Type Conversion in WHERE
|
|
41
|
+
- **Symptom**: Query returns wrong results or runs slowly because an index is not used. No error is raised.
|
|
42
|
+
- **Cause**: Comparing a column to a literal of a different type forces an implicit cast. E.g., comparing an integer column to a string literal `WHERE id = '123'`, or a varchar column to a number. Some databases cast the column (index unusable); others cast the literal (usually OK).
|
|
43
|
+
- **Strategy**: 1. Identify the column type from the schema. 2. Ensure the literal or bound parameter matches the column type exactly. 3. In application code, use parameterized queries with the correct type binding. 4. Run `EXPLAIN ANALYZE` to confirm the plan does not include a cast on the column side.
|
|
44
|
+
- **Tool sequence**: shell_exec (`\d table_name` or schema query) → file_read (query) → file_edit (cast literal or fix parameter type)
|
|
45
|
+
- **Pitfall**: Do NOT cast the column in the WHERE clause to match the literal: `WHERE CAST(id AS VARCHAR) = '123'` — this prevents index use. Cast the literal instead: `WHERE id = 123`.
|
|
46
|
+
|
|
47
|
+
### Missing Transaction Rollback on Error
|
|
48
|
+
- **Symptom**: Partial data written to the database when an error occurs mid-operation. Data is in an inconsistent state.
|
|
49
|
+
- **Cause**: Multiple related DML statements (INSERT, UPDATE, DELETE) are not wrapped in a transaction, or the error handling path does not issue a ROLLBACK.
|
|
50
|
+
- **Strategy**: 1. Wrap all related DML in `BEGIN; ... COMMIT;`. 2. In application code, use try/catch with ROLLBACK in the catch block. 3. Use database-level constraints (FK, UNIQUE, CHECK) as the last line of defense. 4. Test the error path explicitly.
|
|
51
|
+
- **Tool sequence**: grep (`INSERT\|UPDATE\|DELETE`) → file_read (transaction boundary) → file_edit (add BEGIN/COMMIT/ROLLBACK)
|
|
52
|
+
- **Pitfall**: Do NOT issue COMMIT before verifying all statements succeeded. Commit only at the outermost transaction boundary.
|
|
53
|
+
|
|
54
|
+
### Missing Index on Foreign Key
|
|
55
|
+
- **Symptom**: Deletes or updates on parent table are slow; parent-side queries perform Seq Scans on child table.
|
|
56
|
+
- **Cause**: Foreign key columns on the child table are not indexed. The database must scan the entire child table to enforce FK constraints on parent modification.
|
|
57
|
+
- **Strategy**: 1. Identify all FK columns in the schema. 2. For each FK column, check if an index exists: `\d child_table`. 3. Add index: `CREATE INDEX ON child_table (parent_id);`.
|
|
58
|
+
- **Tool sequence**: shell_exec (schema inspection) → file_edit (migration to add index)
|
|
59
|
+
- **Pitfall**: Do NOT add the index to the parent's primary key column — add it to the FK column on the child table.
|
|
60
|
+
|
|
61
|
+
## Verification
|
|
62
|
+
Run: `EXPLAIN ANALYZE <query>` for any query touching tables with >10k rows.
|
|
63
|
+
- Target: no Seq Scan on large tables (unless the query reads most of the table).
|
|
64
|
+
- Target: actual rows ≈ estimated rows (large divergence indicates stale statistics — run `ANALYZE table_name`).
|
|
65
|
+
|
|
66
|
+
## Validation Checklist
|
|
67
|
+
- [ ] `EXPLAIN ANALYZE` reviewed for all slow queries (>100ms)
|
|
68
|
+
- [ ] No `= NULL` or `!= NULL` comparisons in WHERE clauses
|
|
69
|
+
- [ ] All function-wrapped column predicates reviewed for index usage
|
|
70
|
+
- [ ] All multi-statement DML wrapped in explicit transactions
|
|
71
|
+
- [ ] FK columns on child tables have indexes
|
|
72
|
+
- [ ] `NOT IN (subquery)` replaced with `NOT EXISTS` where subquery may return NULLs
|
|
73
|
+
- [ ] Parameterized queries used — no string-concatenated SQL
|
|
74
|
+
- [ ] `ANALYZE` run after bulk data changes to refresh statistics
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: svelte
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.91
|
|
5
|
+
|
|
6
|
+
# Svelte — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the Svelte compiler error in full — it includes the file, line, column, and a description. Runtime errors appear in the browser console; compiler errors appear in the terminal during build.
|
|
9
|
+
|
|
10
|
+
## Quick Reference
|
|
11
|
+
- **'X' is not defined** — Variable used in template not declared in `<script>`.
|
|
12
|
+
- **'store' is not a store** — Variable used with `$` prefix is not a Svelte store.
|
|
13
|
+
- **Uncaught ReferenceError: X is not defined** — SSR/hydration mismatch or browser-only API used during SSR.
|
|
14
|
+
- **Each block must have a key expression** — Missing `(key)` in `{#each}`.
|
|
15
|
+
- **Cannot read properties of undefined** — Slot prop or store value not yet initialized.
|
|
16
|
+
|
|
17
|
+
## Known Error Patterns
|
|
18
|
+
|
|
19
|
+
### Reactive Statement Not Triggering — Mutation vs Reassignment
|
|
20
|
+
- **Symptom**: `$: derivedValue = compute(arr)` does not update when `arr` is mutated (e.g., `arr.push(item)`). UI stays stale.
|
|
21
|
+
- **Cause**: Svelte's reactivity is triggered by assignment. Mutating an array or object in place (`.push`, `.pop`, property assignment without reassignment) does not trigger reactivity because no assignment to the top-level variable occurs.
|
|
22
|
+
- **Strategy**: 1. After any mutation, reassign the variable: `arr.push(item); arr = arr;`. 2. Use immutable patterns: `arr = [...arr, item]` for push, `arr = arr.filter(...)` for remove. 3. For objects: `obj = { ...obj, key: value }` or `obj.key = value; obj = obj;`.
|
|
23
|
+
- **Tool sequence**: grep (mutation calls on reactive variable) → file_read → file_edit (add reassignment after mutation or switch to immutable pattern)
|
|
24
|
+
- **Pitfall**: Do NOT mutate a prop from inside a child component. Props flow down; use an event or a writable store for two-way data flow.
|
|
25
|
+
|
|
26
|
+
### Store Subscription Not Unsubscribed
|
|
27
|
+
- **Symptom**: Memory leak or stale callbacks after component is destroyed. Effects fire on unmounted components. Warning: "Cannot update a component after it has been destroyed."
|
|
28
|
+
- **Cause**: Manual store subscription using `store.subscribe(callback)` returns an unsubscribe function. If not called in `onDestroy`, the callback keeps firing after the component is unmounted.
|
|
29
|
+
- **Strategy**: 1. For manual subscriptions, always unsubscribe in `onDestroy`: `const unsub = store.subscribe(cb); onDestroy(unsub);`. 2. Use the `$store` auto-subscription syntax instead — Svelte automatically unsubscribes when the component is destroyed: `$myStore` in the template or reactive block.
|
|
30
|
+
- **Tool sequence**: grep (`\.subscribe\(`) → file_read (onDestroy presence) → file_edit (add onDestroy(unsub) or replace with $ syntax)
|
|
31
|
+
- **Pitfall**: Do NOT call `unsub()` in `onMount` return — that unsubscribes too early. Call it in `onDestroy`.
|
|
32
|
+
|
|
33
|
+
### Slot Prop Undefined
|
|
34
|
+
- **Symptom**: `Cannot read properties of undefined (reading 'x')` when accessing a slot prop. The slot renders but prop values are undefined.
|
|
35
|
+
- **Cause**: The parent passes a slot without the expected `let:propName` binding, or the child component's `<slot>` element does not pass the prop correctly with the named attribute.
|
|
36
|
+
- **Strategy**: 1. In the child component, verify the slot exports the prop: `<slot propName={value} />`. 2. In the parent, bind the prop with `let:propName`: `<svelte:fragment slot="name" let:propName>`. 3. Check for typos in the prop name — they must match exactly.
|
|
37
|
+
- **Tool sequence**: file_read (child component slot definition) → file_read (parent usage) → file_edit (add or fix let: binding)
|
|
38
|
+
- **Pitfall**: Slot props are only available within the slot markup in the parent. Do NOT try to use them outside the `<svelte:fragment>` or slot element.
|
|
39
|
+
|
|
40
|
+
### SSR Hydration Mismatch
|
|
41
|
+
- **Symptom**: Console warning: `Hydration mismatch` or elements flicker/reset on initial page load. Content rendered server-side differs from client-side initial render.
|
|
42
|
+
- **Cause**: Code that runs differently on server vs client: `Math.random()`, `Date.now()`, `window`/`document` access, locale-dependent formatting, or data fetched at different times.
|
|
43
|
+
- **Strategy**: 1. Identify the non-deterministic or browser-only value. 2. For browser-only APIs, guard with `if (browser)` from `$app/environment`, or use `onMount` (which only runs on client). 3. For random/time values, generate them on the server and pass as props, or synchronize the seed. 4. For locale: use a consistent locale setting shared between server and client.
|
|
44
|
+
- **Tool sequence**: file_read (component that flickers) → grep (`window\|document\|Math.random\|Date.now`) → file_edit (move to onMount or add browser guard)
|
|
45
|
+
- **Pitfall**: Do NOT wrap entire components with `{#if browser}` as a shortcut — this suppresses SSR entirely and loses SEO benefits. Fix the specific non-deterministic expression.
|
|
46
|
+
|
|
47
|
+
### Each Block Key Missing
|
|
48
|
+
- **Symptom**: `[svelte] warning: Each block requires a (key) expression` — list items re-render incorrectly, animations are wrong, component state is misattributed when list changes.
|
|
49
|
+
- **Cause**: `{#each items as item}` without `(item.id)` makes Svelte use positional diffing. Reordering, adding, or removing items confuses component identity.
|
|
50
|
+
- **Strategy**: 1. Add a unique key: `{#each items as item (item.id)}`. 2. The key must be a primitive (string, number) or something serializable. 3. Do NOT use array index as a key when items can be reordered or deleted.
|
|
51
|
+
- **Tool sequence**: grep (`{#each`) → file_read (template) → file_edit (add key expression)
|
|
52
|
+
- **Pitfall**: The key goes in parentheses after the item variable: `(item.id)`. Do NOT use `:key` (that is Vue syntax).
|
|
53
|
+
|
|
54
|
+
### Reactive Declaration Ordering
|
|
55
|
+
- **Symptom**: `$: b = a * 2` uses `a` which is defined by another reactive statement `$: a = fetch(...)`. `b` always sees the previous value of `a`.
|
|
56
|
+
- **Cause**: Svelte orders reactive statements topologically based on declared dependencies. If the dependency graph is not clear (e.g., both depend on the same store side-effect), ordering can be non-intuitive.
|
|
57
|
+
- **Strategy**: 1. Ensure reactive statements form a clear dependency graph. 2. If `b` depends on `a`, write `$: b = a * 2` AFTER `$: a = compute()` in the file, and make the dependency explicit (read `a` in the expression for `b`). 3. For complex derived state, use a store with a derived: `const b = derived(aStore, $a => $a * 2)`.
|
|
58
|
+
- **Tool sequence**: file_read (reactive block order) → file_edit (reorder or extract to derived store)
|
|
59
|
+
- **Pitfall**: Do NOT rely on file-order alone when reactive statements have side effects. Explicit data dependencies are more reliable.
|
|
60
|
+
|
|
61
|
+
## Verification
|
|
62
|
+
Run: `svelte-check` for static type and template checking (with TypeScript).
|
|
63
|
+
- `vite build` or `svelte-kit build` for full compilation.
|
|
64
|
+
- Browser console must show zero Svelte hydration warnings on initial load.
|
|
65
|
+
|
|
66
|
+
## Validation Checklist
|
|
67
|
+
- [ ] All array/object mutations followed by reassignment (`arr = arr`) or use immutable update patterns
|
|
68
|
+
- [ ] All `store.subscribe()` calls have matching `onDestroy(unsub)` or replaced with `$store` syntax
|
|
69
|
+
- [ ] All `{#each}` blocks have a `(key)` expression using stable unique ID
|
|
70
|
+
- [ ] Browser-only APIs guarded with `if (browser)` or moved to `onMount`
|
|
71
|
+
- [ ] Slot props bound with `let:propName` in parent matching child's slot attribute
|
|
72
|
+
- [ ] `svelte-check` reports zero errors
|
|
73
|
+
- [ ] Reactive declaration order reflects data dependency order
|
|
74
|
+
- [ ] No component mutations to received props (use events or writable stores)
|