@yuaone/core 0.8.5 → 0.9.1
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/bash.md +74 -0
- package/dist/skills/languages/c.md +76 -0
- package/dist/skills/languages/cpp.md +75 -0
- package/dist/skills/languages/csharp.md +77 -0
- package/dist/skills/languages/cuda.md +80 -0
- package/dist/skills/languages/dart.md +75 -0
- package/dist/skills/languages/docker.md +80 -0
- package/dist/skills/languages/elixir.md +80 -0
- package/dist/skills/languages/gdscript.md +80 -0
- package/dist/skills/languages/go.md +77 -0
- package/dist/skills/languages/haskell.md +80 -0
- package/dist/skills/languages/java.md +77 -0
- package/dist/skills/languages/javascript.md +73 -0
- package/dist/skills/languages/kotlin.md +75 -0
- package/dist/skills/languages/lua.md +79 -0
- package/dist/skills/languages/php.md +73 -0
- package/dist/skills/languages/python.md +89 -0
- package/dist/skills/languages/r.md +80 -0
- package/dist/skills/languages/react.md +86 -0
- package/dist/skills/languages/ruby.md +78 -0
- package/dist/skills/languages/rust.md +77 -0
- package/dist/skills/languages/solidity.md +81 -0
- package/dist/skills/languages/sql.md +74 -0
- package/dist/skills/languages/svelte.md +74 -0
- package/dist/skills/languages/swift.md +74 -0
- package/dist/skills/languages/terraform.md +80 -0
- package/dist/skills/languages/typescript.md +110 -0
- package/dist/skills/languages/verilog.md +80 -0
- package/dist/skills/languages/vue.md +73 -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/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,77 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: go
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.95
|
|
5
|
+
|
|
6
|
+
# Go — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the exact compiler error message first. Go errors are terse but precise — the line number, symbol name, and package path are always actionable.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **declared and not used** — Variable declared but never read. Remove or use it.
|
|
12
|
+
- **undefined: X** — Symbol not found in scope. Missing import or typo.
|
|
13
|
+
- **cannot use X as type Y** — Type mismatch in assignment or function call.
|
|
14
|
+
- **nil pointer dereference** — Accessing a field/method on a nil pointer.
|
|
15
|
+
- **too many arguments in call** / **not enough arguments** — Arity mismatch.
|
|
16
|
+
- **imported and not used** — Import declared but no symbol from it used.
|
|
17
|
+
- **interface does not implement** — Missing method(s) for interface satisfaction.
|
|
18
|
+
- **context deadline exceeded** — Context timed out before operation completed.
|
|
19
|
+
- **goroutine leak** — goroutine blocked forever on channel or lock.
|
|
20
|
+
- **data race** — Two goroutines accessing same memory without synchronization.
|
|
21
|
+
|
|
22
|
+
## Known Error Patterns
|
|
23
|
+
|
|
24
|
+
### Pattern: declared and not used
|
|
25
|
+
|
|
26
|
+
- **symptom**: `./main.go:12:5: x declared and not used`
|
|
27
|
+
- **cause**: Go requires every declared variable to be read at least once. Assigning to `_` or simply not reading the variable causes a compile error.
|
|
28
|
+
- **strategy**: 1. Read the line where the variable is declared. 2. Determine if the variable is genuinely unused — delete it. 3. If the value is needed for a side effect only (e.g., error return), assign to `_`: `_ = val`. 4. If the variable was meant to be used elsewhere, trace where it should be consumed and add the usage.
|
|
29
|
+
- **toolSequence**: file_read (declaration line) → file_edit (remove or assign to `_`)
|
|
30
|
+
- **pitfall**: Do NOT assign everything to `_` indiscriminately. If the value is an error, silently discarding it hides real failures.
|
|
31
|
+
|
|
32
|
+
### Pattern: undefined: X (import path / symbol)
|
|
33
|
+
|
|
34
|
+
- **symptom**: `./main.go:8:10: undefined: SomeFunc` or `undefined: pkg.SomeType`
|
|
35
|
+
- **cause**: Either (a) the import path is wrong, (b) the package is not added to go.mod, (c) the symbol is unexported (lowercase), or (d) there is a typo in the symbol name.
|
|
36
|
+
- **strategy**: 1. Grep for the symbol definition in the project. 2. If found, check whether the import path matches the directory path. 3. If not found, check go.mod for the module — run `go get module@version` if missing. 4. If the symbol starts with a lowercase letter it is unexported — use the exported version or define a wrapper.
|
|
37
|
+
- **toolSequence**: grep (symbol name) → file_read (go.mod) → shell_exec (`go get <module>`) → file_edit (fix import path or symbol name)
|
|
38
|
+
- **pitfall**: Do NOT confuse package name with directory name — Go package name is the `package` declaration inside the file, not the directory.
|
|
39
|
+
|
|
40
|
+
### Pattern: goroutine leak (missing defer cancel)
|
|
41
|
+
|
|
42
|
+
- **symptom**: Memory grows unboundedly over time; `runtime.NumGoroutine()` keeps increasing. Often paired with `context.WithCancel` or `context.WithTimeout` never cancelled.
|
|
43
|
+
- **cause**: Every `context.WithCancel` or `context.WithTimeout` allocates resources that are only freed when the cancel function is called. If `cancel()` is never called (or called only in the non-error path), the goroutine and timer leak.
|
|
44
|
+
- **strategy**: 1. Grep for `context.WithCancel` and `context.WithTimeout` in the file. 2. Verify that immediately after each call there is a `defer cancel()`. 3. Place `defer cancel()` on the very next line after the `ctx, cancel :=` assignment — before any error-returning calls. 4. Verify with `go vet` and the `context` linter.
|
|
45
|
+
- **toolSequence**: grep (`WithCancel\|WithTimeout`) → file_read → file_edit (add `defer cancel()` immediately after assignment)
|
|
46
|
+
- **pitfall**: Do NOT place `defer cancel()` inside an `if err == nil` block — that leaves it uncalled on the error path.
|
|
47
|
+
|
|
48
|
+
### Pattern: nil pointer dereference
|
|
49
|
+
|
|
50
|
+
- **symptom**: `panic: runtime error: invalid memory address or nil pointer dereference` with a goroutine stack trace.
|
|
51
|
+
- **cause**: A pointer, interface, map, slice, or channel variable is `nil` when a field or method is accessed on it. Common sources: uninitialized struct fields, function returning `nil` error value cast to an interface, or a map not initialized with `make`.
|
|
52
|
+
- **strategy**: 1. Read the stack trace line number to find the exact dereference. 2. Trace backwards to where the variable was assigned — check every code path, including early returns. 3. Add a nil guard: `if ptr == nil { return fmt.Errorf("...") }`. 4. For maps, ensure initialization: `m = make(map[K]V)`. 5. For interfaces, avoid `var err error; return err` when the concrete type is nil but the interface is non-nil.
|
|
53
|
+
- **toolSequence**: file_read (panic line from stack trace) → grep (variable assignment) → file_edit (add nil check or initialize)
|
|
54
|
+
- **pitfall**: Do NOT confuse a nil interface with a nil pointer inside the interface. A `(*MyType)(nil)` stored in an `error` interface is NOT nil at the interface level.
|
|
55
|
+
|
|
56
|
+
### Pattern: interface satisfaction error
|
|
57
|
+
|
|
58
|
+
- **symptom**: `*MyStruct does not implement MyInterface (missing method Foo)` or `cannot use *MyStruct as type MyInterface`
|
|
59
|
+
- **cause**: The concrete type is missing one or more methods required by the interface, the receiver type is wrong (pointer vs value), or the method signature differs (parameter or return type mismatch).
|
|
60
|
+
- **strategy**: 1. Read the interface definition (grep the interface name). 2. List all required methods. 3. Grep for the method on the concrete type. 4. If missing, implement it. 5. If receiver is value but interface requires pointer (or vice versa), adjust the method receiver or the assignment (`&myStruct{}`). 6. Add a compile-time check: `var _ MyInterface = (*MyStruct)(nil)`.
|
|
61
|
+
- **toolSequence**: grep (interface name) → file_read → grep (method name on struct) → file_edit (implement missing method or fix receiver)
|
|
62
|
+
- **pitfall**: Do NOT implement the method on the value receiver when the interface is satisfied only by the pointer receiver — only `*T` satisfies both pointer and value receiver methods, not the other way around.
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
Run: `go build ./...` and `go vet ./...`
|
|
66
|
+
- `go build` exit 0 = no compile errors.
|
|
67
|
+
- `go vet` exit 0 = no common correctness issues.
|
|
68
|
+
- For race detection: `go test -race ./...`
|
|
69
|
+
|
|
70
|
+
## Validation Checklist
|
|
71
|
+
- [ ] `go build ./...` exits 0 with no output
|
|
72
|
+
- [ ] `go vet ./...` exits 0 with no output
|
|
73
|
+
- [ ] Every `context.WithCancel` / `context.WithTimeout` is immediately followed by `defer cancel()`
|
|
74
|
+
- [ ] No nil pointer dereferences — all pointers nil-checked before use
|
|
75
|
+
- [ ] Interface satisfaction verified (either compiler confirms or explicit `var _ I = (*T)(nil)` check)
|
|
76
|
+
- [ ] No imported packages unused; no variables declared but unused
|
|
77
|
+
- [ ] Maps initialized with `make()` before write
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: haskell
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.88
|
|
5
|
+
|
|
6
|
+
# Haskell — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the full GHC error including source location, the constraint context, and the inferred vs expected types. Haskell errors often appear far from the actual source of the type mismatch — read the constraint trail.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **"No instance for (Typeclass x)"** — Missing typeclass instance for a type.
|
|
12
|
+
- **"Couldn't match expected type"** — Type mismatch; read both types carefully.
|
|
13
|
+
- **"Ambiguous type variable"** — GHC cannot determine which instance to use; add type annotation.
|
|
14
|
+
- **"Non-exhaustive patterns"** — Case expression or function definition missing a branch.
|
|
15
|
+
- **"Variable not in scope"** — Name not imported or not in scope; check module imports.
|
|
16
|
+
- **"Couldn't match type 'IO a' with 'a'"** — Forgetting to bind (>>=) or `<-` in do notation.
|
|
17
|
+
- **"Occurs check: cannot construct the infinite type"** — Recursive type without newtype wrapper.
|
|
18
|
+
- **"Module 'X' does not export 'y'"** — Trying to import a name that is not exported.
|
|
19
|
+
|
|
20
|
+
## Known Error Patterns
|
|
21
|
+
|
|
22
|
+
### No Instance For — Missing Typeclass
|
|
23
|
+
- **Symptom**: `No instance for (Show MyType) arising from a use of 'print'`; GHC refuses to compile even though the logic seems correct.
|
|
24
|
+
- **Cause**: A typeclass method is used on a type that has not derived or implemented the required instance. Common cases: `Show` needed for printing, `Eq` needed for `==`, `Ord` needed for sorting, `FromJSON`/`ToJSON` needed for Aeson.
|
|
25
|
+
- **Strategy**: 1. Read the error — it says exactly which typeclass is missing for which type. 2. If the type is yours, add a deriving clause: `data MyType = ... deriving (Show, Eq, Ord)`. 3. For more complex instances (e.g., `FromJSON` for a custom type), write the instance manually or use Template Haskell: `$(deriveJSON defaultOptions ''MyType)`. 4. For orphan instances (instance for a type you don't own in a module you don't own), create a `newtype` wrapper. 5. Check that the required module is imported: `import Data.Aeson (FromJSON, ToJSON)`.
|
|
26
|
+
- **Tool sequence**: file_read (type definition) → file_edit (add deriving clause or manual instance) → shell_exec (`cabal build` or `stack build`)
|
|
27
|
+
- **Pitfall**: Do NOT add a `newtype` wrapper just to avoid an orphan instance warning if you can define the instance in the same module as the type — orphan instances cause import order dependencies.
|
|
28
|
+
|
|
29
|
+
### Space Leak — Lazy Evaluation Accumulation
|
|
30
|
+
- **Symptom**: Memory usage grows linearly with input size for operations that should be constant space (e.g., `foldl sum`); program eventually runs out of memory on large inputs.
|
|
31
|
+
- **Cause**: Haskell is lazy by default — thunks accumulate without being evaluated. `foldl (+) 0 [1..1000000]` builds a chain of a million unevaluated additions before computing anything. The result is held as a thunk until forced.
|
|
32
|
+
- **Strategy**: 1. Replace `foldl` with `foldl'` (strict left fold) from `Data.List`: `import Data.List (foldl')`. 2. Use `BangPatterns` or `$!` for strict accumulation: `go !acc (x:xs) = go (acc + x) xs`. 3. Use `seq` to force evaluation: `let !x = expensiveComputation`. 4. Profile with `+RTS -hc -p` to identify which thunks are accumulating. 5. Consider using strict data structures (`Data.Map.Strict` instead of `Data.Map.Lazy`).
|
|
33
|
+
- **Tool sequence**: grep (`foldl `, `Data.Map` without `.Strict`) → file_read → file_edit (replace with strict versions)
|
|
34
|
+
- **Pitfall**: Do NOT add `seq` or `!` everywhere blindly — forcing evaluation in the wrong place can change semantics for infinite lists and lazy I/O.
|
|
35
|
+
|
|
36
|
+
### Non-Exhaustive Patterns — Missing Case Branch
|
|
37
|
+
- **Symptom**: `Non-exhaustive patterns in function foo` at runtime; `ghc -W` warns `Pattern match(es) are non-exhaustive`; program crashes on an input that wasn't tested.
|
|
38
|
+
- **Cause**: A `case` expression or multi-equation function definition does not cover all possible inputs. Common cases: not handling `Nothing` in a `Maybe`, missing constructors in a sum type `case`, not handling the empty list `[]`.
|
|
39
|
+
- **Strategy**: 1. Enable `-Wincomplete-patterns` in GHC options (or use `-Wall`). 2. Read which patterns are missing from the warning. 3. Add the missing cases — do not use a wildcard `_ -> error "impossible"` unless you can prove it is truly unreachable. 4. For `Maybe`, always handle both `Just x` and `Nothing`. 5. For sum types you own, add a constructor and let GHC's exhaustiveness checker find all unhandled cases.
|
|
40
|
+
- **Tool sequence**: shell_exec (`ghc -Wall -fno-code MyFile.hs`) → file_read (function with non-exhaustive patterns) → file_edit (add missing case branches)
|
|
41
|
+
- **Pitfall**: Do NOT use `_ -> undefined` or `_ -> error "unreachable"` in case expressions — if the case is truly exhaustive, GHC will tell you; if it is not, `error` crashes the program.
|
|
42
|
+
|
|
43
|
+
### Ambiguous Type Variable — Missing Annotation
|
|
44
|
+
- **Symptom**: `Ambiguous type variable 'a0' arising from a use of 'show'`; GHC knows a typeclass constraint is needed but cannot choose which instance to use without more information.
|
|
45
|
+
- **Cause**: An expression has a polymorphic type and the context does not constrain it sufficiently. Common cases: `show (read "123")` — GHC doesn't know which type to read into; `mempty` when the monoid type is unclear; numeric literals without context.
|
|
46
|
+
- **Strategy**: 1. Add a type annotation at the ambiguous expression: `show (read "123" :: Int)`. 2. Add a type signature to the function containing the ambiguous expression. 3. Use `ScopedTypeVariables` extension to annotate inner expressions. 4. For `defaulting` issues with numeric types, GHC may default to `Integer` — add explicit `:: Double` or `:: Int` annotations.
|
|
47
|
+
- **Tool sequence**: file_read (ambiguous expression location) → file_edit (add :: TypeAnnotation at the expression or full function signature)
|
|
48
|
+
- **Pitfall**: Do NOT use `asTypeOf` to hint types unless you understand its semantics — add an explicit type annotation instead, which documents intent clearly.
|
|
49
|
+
|
|
50
|
+
### Import Conflict — Module.Function vs Unqualified
|
|
51
|
+
- **Symptom**: `Ambiguous occurrence 'lookup'` — the name is defined in multiple imported modules; compilation fails.
|
|
52
|
+
- **Cause**: Multiple modules export the same name (e.g., `lookup` from `Prelude` and `Data.Map`, `fromList` from `Data.Set` and `Data.Map`). Both are in scope unqualified.
|
|
53
|
+
- **Strategy**: 1. Use qualified imports for container modules: `import qualified Data.Map.Strict as Map`, `import qualified Data.Set as Set`. 2. Then use `Map.lookup`, `Set.fromList` to disambiguate. 3. Alternatively, use explicit import lists to import only what's needed: `import Data.Map (Map, fromList)`. 4. Hide Prelude clashes: `import Prelude hiding (lookup)`. 5. Enable `PackageImports` extension if the same module name exists in multiple packages.
|
|
54
|
+
- **Tool sequence**: grep (`^import `) → file_read → file_edit (add qualified imports or explicit import lists)
|
|
55
|
+
- **Pitfall**: Do NOT hide Prelude names without a good reason — other readers of the code expect Prelude names to be available and unqualified.
|
|
56
|
+
|
|
57
|
+
### IO vs Pure Confusion — Missing Bind in do Notation
|
|
58
|
+
- **Symptom**: `Couldn't match type 'IO String' with 'String'`; `Couldn't match expected type '[Char]' with actual type 'IO [Char]'`.
|
|
59
|
+
- **Cause**: In do notation, `let x = getLine` binds the IO action itself (not the result) to `x`. To extract the value from an IO action, use `<-`: `x <- getLine`. Forgetting `<-` leaves the monadic wrapper.
|
|
60
|
+
- **Strategy**: 1. Read the do block carefully — every `IO a` value that needs the inner `a` must use `<-`. 2. `let x = pureExpression` for pure values; `x <- ioAction` for IO actions. 3. For `Maybe`/`Either` in `ExceptT` stacks, use `lift` or `liftIO` to bring IO actions into the monad transformer context. 4. If you need to use a pure value inside IO, it is already usable — no wrapping needed.
|
|
61
|
+
- **Tool sequence**: file_read (do block with type error) → file_edit (change `let x =` to `x <-` for IO actions)
|
|
62
|
+
- **Pitfall**: Do NOT use `unsafePerformIO` to force IO values into pure context — this breaks referential transparency and causes non-deterministic behavior.
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
Run: `cabal build 2>&1` or `stack build 2>&1`
|
|
66
|
+
- Zero errors, zero warnings with `-Wall -Wincomplete-patterns`.
|
|
67
|
+
- Run HLint: `hlint src/` — apply all "Suggestion" level hints.
|
|
68
|
+
- Run tests: `cabal test` or `stack test`.
|
|
69
|
+
|
|
70
|
+
## Validation Checklist
|
|
71
|
+
- [ ] GHC build passes with `-Wall` and zero warnings
|
|
72
|
+
- [ ] All `case` expressions and function equations are exhaustive
|
|
73
|
+
- [ ] `foldl` replaced with `foldl'` in all non-lazy contexts
|
|
74
|
+
- [ ] All container module imports are qualified (`Data.Map` as `Map`, etc.)
|
|
75
|
+
- [ ] All ambiguous type variables have explicit annotations
|
|
76
|
+
- [ ] No `error` or `undefined` in production code paths
|
|
77
|
+
- [ ] `Maybe` and `Either` error cases handled (no partial functions like `head` on empty list)
|
|
78
|
+
- [ ] `unsafePerformIO` and `unsafeCoerce` not used
|
|
79
|
+
- [ ] HLint passes with no errors
|
|
80
|
+
- [ ] All exported functions have type signatures
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: java
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.95
|
|
5
|
+
|
|
6
|
+
# Java — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the full stack trace including the cause chain (`Caused by:`). Java exceptions cascade — the root cause is at the bottom, not the top.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **NullPointerException** — Accessing method/field on a null reference.
|
|
12
|
+
- **ClassCastException** — Casting an object to an incompatible type.
|
|
13
|
+
- **ConcurrentModificationException** — Modifying a collection while iterating it.
|
|
14
|
+
- **OutOfMemoryError: Java heap space** — Heap exhausted. Check for memory leaks.
|
|
15
|
+
- **StackOverflowError** — Unbounded recursion or circular call chain.
|
|
16
|
+
- **ClassNotFoundException** — Class not on classpath at runtime.
|
|
17
|
+
- **NoSuchMethodError** — Compiled against different version than runtime JAR.
|
|
18
|
+
- **IllegalArgumentException** — Invalid argument passed to method.
|
|
19
|
+
- **IllegalStateException** — Method called at wrong lifecycle phase.
|
|
20
|
+
- **checked exception not handled** — Compile error: checked exception must be caught or declared.
|
|
21
|
+
|
|
22
|
+
## Known Error Patterns
|
|
23
|
+
|
|
24
|
+
### Pattern: NullPointerException
|
|
25
|
+
|
|
26
|
+
- **symptom**: `java.lang.NullPointerException` at a specific stack frame, optionally with JDK 14+ helpful NPE message: `Cannot invoke "String.length()" because "str" is null`
|
|
27
|
+
- **cause**: A variable holds `null` when a method call or field access is performed. Common sources: uninitialized fields, method returning null, optional result not checked, collection `get()` returning null for missing key.
|
|
28
|
+
- **strategy**: 1. Read the stack trace to find the exact line. 2. Identify which variable is null at that line. 3. Trace backwards to where it was assigned. 4. Add a null check (`if (x != null)`) or use `Optional<T>` and `.orElse()`/`.orElseThrow()`. 5. For Java 8+, prefer `Objects.requireNonNull(x, "x must not be null")` at entry points. 6. Use `@NonNull` / `@Nullable` annotations for documentation.
|
|
29
|
+
- **toolSequence**: file_read (stack trace line) → grep (variable assignment) → file_edit (add null check or Optional)
|
|
30
|
+
- **pitfall**: Do NOT add null checks everywhere defensively without understanding why null is reached — find the source and fix it there.
|
|
31
|
+
|
|
32
|
+
### Pattern: ClassCastException
|
|
33
|
+
|
|
34
|
+
- **symptom**: `java.lang.ClassCastException: class Foo cannot be cast to class Bar`
|
|
35
|
+
- **cause**: An object of type `Foo` was stored in a reference of type `Object` (or a supertype) and then cast to `Bar`, but the actual runtime type is incompatible. Common in legacy collections (pre-generics), deserialization, or downcasting without `instanceof` check.
|
|
36
|
+
- **strategy**: 1. Read the exact class names in the exception. 2. Find where the cast is performed. 3. Add an `instanceof` check before the cast: `if (obj instanceof Bar) { Bar b = (Bar) obj; }`. 4. For Java 16+, use pattern matching: `if (obj instanceof Bar b) { ... }`. 5. If the cast is in serialization/deserialization code, verify the serialized type matches the expected type.
|
|
37
|
+
- **toolSequence**: file_read (cast line) → grep (where the object was originally stored) → file_edit (add instanceof check)
|
|
38
|
+
- **pitfall**: Do NOT suppress with a try/catch around the cast — understand why the wrong type is being stored and fix the storage point.
|
|
39
|
+
|
|
40
|
+
### Pattern: ConcurrentModificationException
|
|
41
|
+
|
|
42
|
+
- **symptom**: `java.util.ConcurrentModificationException` while iterating a List, Map, or Set
|
|
43
|
+
- **cause**: The collection was structurally modified (add/remove) while an iterator or enhanced for-loop is active over it. The fail-fast iterator detects the modification counter change and throws.
|
|
44
|
+
- **strategy**: 1. Find the iteration loop. 2. Find the modification inside or outside the loop. 3. Solutions by case: (a) Removing during iteration: use `Iterator.remove()` explicitly. (b) Adding during iteration: collect items to add in a separate list, add them after the loop. (c) Concurrent modification from another thread: use `CopyOnWriteArrayList`, `ConcurrentHashMap`, or synchronize access. 4. For Java streams, collect results to a new list instead of modifying the source.
|
|
45
|
+
- **toolSequence**: file_read (iteration loop) → file_edit (replace with Iterator.remove() or copy-then-modify pattern)
|
|
46
|
+
- **pitfall**: Do NOT switch to `CopyOnWriteArrayList` for single-threaded code — it has high write cost. Use Iterator.remove() for sequential removal.
|
|
47
|
+
|
|
48
|
+
### Pattern: OutOfMemoryError (heap space)
|
|
49
|
+
|
|
50
|
+
- **symptom**: `java.lang.OutOfMemoryError: Java heap space` — JVM terminates or GC overhead limit exceeded
|
|
51
|
+
- **cause**: Heap is exhausted. Root causes: (a) unbounded collection growth (cache without eviction), (b) large data loaded entirely into memory, (c) object retention via static fields or listener/callback leaks, (d) insufficient -Xmx setting for workload.
|
|
52
|
+
- **strategy**: 1. Take a heap dump: `-XX:+HeapDumpOnOutOfMemoryError`. 2. Analyze with VisualVM or Eclipse MAT — find the largest retained object. 3. If it is a collection, check the code that populates it — add size bounds or eviction (LRU cache). 4. If it is caused by large data, use streaming (BufferedReader, InputStream) instead of loading entirely. 5. If it is a listener leak, ensure listeners are removed in teardown/close methods. 6. As a last resort, increase `-Xmx` in JVM args, but fix the leak first.
|
|
53
|
+
- **toolSequence**: grep (`new ArrayList\|new HashMap\|static.*List\|static.*Map`) → file_read (population logic) → file_edit (add size limit or streaming)
|
|
54
|
+
- **pitfall**: Do NOT increase -Xmx without investigating the root cause — it only delays the crash and masks the leak.
|
|
55
|
+
|
|
56
|
+
### Pattern: checked exception not handled
|
|
57
|
+
|
|
58
|
+
- **symptom**: Compile error: `unreported exception IOException; must be caught or declared to be thrown`
|
|
59
|
+
- **cause**: A method that throws a checked exception is called without either (a) surrounding it in a try-catch or (b) declaring the exception in the calling method's `throws` clause.
|
|
60
|
+
- **strategy**: 1. Read which exception is unhandled and which line throws it. 2. Decide the correct response: (a) Handle it locally — wrap in try-catch and either recover or log + rethrow as unchecked. (b) Propagate it — add `throws IOException` (or the specific exception) to the calling method signature. 3. Avoid catching `Exception` broadly — catch the specific checked exception. 4. When rethrowing as unchecked, use `throw new RuntimeException("context message", e)` to preserve the cause.
|
|
61
|
+
- **toolSequence**: file_read (throwing method signature) → file_edit (add try-catch or throws declaration)
|
|
62
|
+
- **pitfall**: Do NOT use `catch (Exception e) { /* ignore */ }` — swallowed exceptions cause silent failures that are very hard to debug later.
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
Run: `mvn compile` or `./gradlew compileJava`
|
|
66
|
+
- Exit 0 = no compile errors.
|
|
67
|
+
- For tests: `mvn test` or `./gradlew test`
|
|
68
|
+
- For static analysis: SpotBugs or `./gradlew spotbugsMain`
|
|
69
|
+
|
|
70
|
+
## Validation Checklist
|
|
71
|
+
- [ ] Compilation succeeds with zero errors
|
|
72
|
+
- [ ] No raw `catch (Exception e) {}` blocks swallowing exceptions silently
|
|
73
|
+
- [ ] All `null` return paths documented and null checks added at consumers
|
|
74
|
+
- [ ] Collections modified during iteration use Iterator.remove() or copy pattern
|
|
75
|
+
- [ ] Checked exceptions either handled locally with recovery or propagated with context
|
|
76
|
+
- [ ] No `instanceof` followed by unchecked cast — use pattern matching (Java 16+)
|
|
77
|
+
- [ ] Static collections have bounded size or explicit eviction policy
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: javascript
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.90
|
|
5
|
+
|
|
6
|
+
# JavaScript — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the full error message including the call stack. JavaScript errors are often discovered at runtime — the stack trace tells you the exact call chain. Enable strict mode and ESLint to catch many issues earlier.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **TypeError: X is not a function** — Value is not callable (undefined/null/wrong type).
|
|
12
|
+
- **TypeError: Cannot read properties of undefined (reading 'x')** — Property access on undefined.
|
|
13
|
+
- **ReferenceError: X is not defined** — Variable not declared or not in scope.
|
|
14
|
+
- **SyntaxError: Cannot use import statement outside a module** — CommonJS vs ESM conflict.
|
|
15
|
+
- **UnhandledPromiseRejection** — Awaited promise rejected without catch.
|
|
16
|
+
- **RangeError: Maximum call stack size exceeded** — Infinite recursion.
|
|
17
|
+
- **TypeError: Assignment to constant variable** — Reassigning const.
|
|
18
|
+
|
|
19
|
+
## Known Error Patterns
|
|
20
|
+
|
|
21
|
+
### Pattern: undefined is not a function (this binding)
|
|
22
|
+
|
|
23
|
+
- **symptom**: `TypeError: this.myMethod is not a function` or `TypeError: undefined is not a function` inside a callback or event handler — `this` is not what was expected
|
|
24
|
+
- **cause**: When a method is passed as a callback, `this` is rebound to the caller's context (often `undefined` in strict mode, or the global object). Common in event listeners, setTimeout callbacks, array methods, and React class component methods.
|
|
25
|
+
- **strategy**: 1. Find where the method is passed as a callback — look for `addEventListener(event, obj.method)` or `arr.forEach(obj.method)`. 2. Bind `this` explicitly: `obj.method.bind(obj)`, or use an arrow function wrapper: `() => obj.method()`. 3. For class methods, use class field arrow functions: `myMethod = () => { ... }` (they bind `this` lexically). 4. For all new code, prefer arrow functions over regular functions in callbacks — arrow functions do not have their own `this`.
|
|
26
|
+
- **toolSequence**: grep (method name passed as callback) → file_read (method definition) → file_edit (add `.bind(this)` or convert to arrow function)
|
|
27
|
+
- **pitfall**: Do NOT use `.bind()` inside render loops or hot paths — it creates a new function reference on every call, causing unnecessary re-renders and GC pressure.
|
|
28
|
+
|
|
29
|
+
### Pattern: Promise not awaited (floating promise)
|
|
30
|
+
|
|
31
|
+
- **symptom**: `UnhandledPromiseRejection: ...` in Node.js, or async errors silently disappearing. A function is called that returns a Promise but the result is not awaited or `.catch()`-ed.
|
|
32
|
+
- **cause**: Calling an async function without `await` or `.then()/.catch()` creates a "floating promise" — it runs independently. If it rejects, the rejection is unhandled and either crashes the process (Node.js 15+) or silently disappears (older Node/browser).
|
|
33
|
+
- **strategy**: 1. Enable the `@typescript-eslint/no-floating-promises` or `no-promise-executor-return` ESLint rule to catch these statically. 2. Find async function calls that are not awaited: grep for function calls whose return type is `Promise`. 3. Add `await` at the call site if you need the result or want errors to propagate. 4. If truly fire-and-forget, add explicit error handling: `myAsync().catch(err => console.error(err))`. 5. In Node.js, register `process.on('unhandledRejection', ...)` to log unhandled rejections during development.
|
|
34
|
+
- **toolSequence**: grep (async function calls without await) → file_read → file_edit (add `await` or `.catch()`)
|
|
35
|
+
- **pitfall**: Do NOT add `void myAsync()` to silence the ESLint rule without adding error handling — errors will still be silently lost.
|
|
36
|
+
|
|
37
|
+
### Pattern: module resolution error (CommonJS vs ESM)
|
|
38
|
+
|
|
39
|
+
- **symptom**: `SyntaxError: Cannot use import statement outside a module` or `Error: require() of ES Module` or `ReferenceError: exports is not defined`
|
|
40
|
+
- **cause**: Mixing CommonJS (`require`/`module.exports`) and ESM (`import`/`export`) module systems in the same project or across package boundaries. Node.js treats `.js` files as CJS by default unless `"type": "module"` is set in `package.json`, or the file uses the `.mjs`/`.cjs` extension.
|
|
41
|
+
- **strategy**: 1. Read the error — it tells you which file is the problem. 2. Check `package.json` for `"type": "module"` or absence. 3. If the project is CJS, change `import/export` to `require/module.exports`. 4. If the project is ESM, change `require` to `import` and ensure all imports include file extensions (`.js`). 5. For files that must be CJS in an ESM project, rename to `.cjs`. 6. For Node.js scripts importing ESM packages, either switch the script to ESM or use dynamic `import()`.
|
|
42
|
+
- **toolSequence**: file_read (package.json "type" field) → file_read (error file) → file_edit (unify module syntax)
|
|
43
|
+
- **pitfall**: Do NOT mix `require` and `import` in the same file — choose one module system and be consistent. Some bundlers allow it but Node.js runtime does not.
|
|
44
|
+
|
|
45
|
+
### Pattern: closure in loop (var vs let)
|
|
46
|
+
|
|
47
|
+
- **symptom**: A loop creates functions (callbacks, event handlers, Promises) that all reference the same final value of the loop variable instead of each iteration's value. Classic: all closures log the same number (e.g., the loop limit).
|
|
48
|
+
- **cause**: `var` is function-scoped, not block-scoped. Inside a `for (var i = 0; ...)` loop, all closures share the same `i` variable — by the time the callback runs, `i` has already reached its final value. `let` creates a new binding per iteration.
|
|
49
|
+
- **strategy**: 1. Find `for (var ...` loops where closures are created inside. 2. Change `var` to `let` — this is the definitive fix for modern JavaScript. 3. For pre-ES6 compatibility, use an IIFE to capture the value: `(function(captured_i) { ... })(i)`. 4. Enable `no-var` ESLint rule to prevent `var` usage entirely.
|
|
50
|
+
- **toolSequence**: grep (`for (var `) → file_read (loop body for closures) → file_edit (change `var` to `let`)
|
|
51
|
+
- **pitfall**: Do NOT convert `var` to `const` in loop initializers — loop variables must be mutable. Use `let`.
|
|
52
|
+
|
|
53
|
+
### Pattern: prototype chain mutation
|
|
54
|
+
|
|
55
|
+
- **symptom**: Adding a property to a built-in prototype (`Array.prototype.myMethod`, `Object.prototype.helper`) causes unexpected properties to appear in `for...in` loops, third-party code breaks, or global behavior changes across the codebase.
|
|
56
|
+
- **cause**: Mutating built-in prototypes adds properties to all instances of that type globally. This pollutes every `for...in` loop that does not use `hasOwnProperty`, conflicts with future JavaScript built-ins of the same name, and breaks libraries that rely on prototype purity.
|
|
57
|
+
- **strategy**: 1. Grep for assignments to `*.prototype.*` on built-in types. 2. Replace with utility functions: instead of `Array.prototype.last = fn`, use a standalone `function last(arr) {}` or a module-level helper. 3. For polyfills, check if the property already exists before adding: `if (!Array.prototype.at) Array.prototype.at = ...`. 4. Use ES6+ class inheritance instead of prototype mutation for custom behavior. 5. Enable ESLint `no-extend-native` rule.
|
|
58
|
+
- **toolSequence**: grep (`prototype\.`) → file_read (each mutation) → file_edit (extract to utility function)
|
|
59
|
+
- **pitfall**: Do NOT add `hasOwnProperty` checks everywhere as a workaround — remove the prototype mutation at the source.
|
|
60
|
+
|
|
61
|
+
## Verification
|
|
62
|
+
Run: `node --check <file>` (syntax check) or `eslint <file>`
|
|
63
|
+
- For projects: `npx eslint src/` or `pnpm run lint`
|
|
64
|
+
- For Node.js module issues: `node -e "require('./file.js')"` or `node --input-type=module`
|
|
65
|
+
|
|
66
|
+
## Validation Checklist
|
|
67
|
+
- [ ] No `var` in loops that create closures — use `let`
|
|
68
|
+
- [ ] All async function calls either awaited or have `.catch()` error handling
|
|
69
|
+
- [ ] Module system is consistent (all CJS or all ESM) — no mixing
|
|
70
|
+
- [ ] No prototype mutation of built-in types
|
|
71
|
+
- [ ] Callbacks that reference `this` use arrow functions or explicit `.bind()`
|
|
72
|
+
- [ ] `eslint` passes with no errors
|
|
73
|
+
- [ ] No `UnhandledPromiseRejection` in Node.js output
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: kotlin
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.95
|
|
5
|
+
|
|
6
|
+
# Kotlin — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the full compiler error or runtime stack trace. Kotlin's type system catches many Java pitfalls at compile time — if an error reaches runtime, trace the `!!` operators and Java interop boundaries first.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **Smart cast to 'T' is impossible** — mutable var cannot be smart cast.
|
|
12
|
+
- **Only safe (?.) or non-null asserted (!!.) calls are allowed** — nullable type used directly.
|
|
13
|
+
- **KotlinNullPointerException** — `!!` forced non-null on a null value.
|
|
14
|
+
- **Type mismatch: inferred type is X but Y was expected** — type inference conflict.
|
|
15
|
+
- **'when' expression must be exhaustive** — sealed class/enum not fully covered.
|
|
16
|
+
- **Suspension functions can be called only within coroutine body** — suspend call outside coroutine.
|
|
17
|
+
- **JobCancellationException** — coroutine scope cancelled before completion.
|
|
18
|
+
- **IllegalStateException: Fragment already added** — Fragment lifecycle misuse.
|
|
19
|
+
|
|
20
|
+
## Known Error Patterns
|
|
21
|
+
|
|
22
|
+
### Pattern: Smart cast impossible (mutable var)
|
|
23
|
+
|
|
24
|
+
- **symptom**: `Smart cast to 'Foo' is impossible, because 'x' is a mutable local variable that could have been changed since the null check`
|
|
25
|
+
- **cause**: Kotlin's smart cast requires that the variable cannot change between the null check and its use. A `var` (mutable variable) can be reassigned by another thread or within a lambda, so the compiler refuses to smart cast it.
|
|
26
|
+
- **strategy**: 1. Read the variable declaration — change `var` to `val` if the variable does not need to be reassigned. 2. If `var` is required, capture the current value in a local `val`: `val current = x; if (current != null) { use(current) }`. 3. For class properties, use a local copy: `val prop = this.nullableProp ?: return`. 4. Use the Elvis operator for early returns: `val safe = nullable ?: return`.
|
|
27
|
+
- **toolSequence**: file_read (null check and usage) → file_edit (change `var` to `val` or capture in local val)
|
|
28
|
+
- **pitfall**: Do NOT add `!!` to suppress the error — it converts a compile-time safety check into a runtime crash.
|
|
29
|
+
|
|
30
|
+
### Pattern: NPE from Java interop (!! operator overuse)
|
|
31
|
+
|
|
32
|
+
- **symptom**: `kotlin.KotlinNullPointerException` at a line containing `!!`, or `NullPointerException` from a Java method call whose return type is platform type (`String!`)
|
|
33
|
+
- **cause**: Java methods return platform types (e.g., `String!`) which Kotlin treats as non-null by default. The `!!` operator forces non-null and crashes if the value is actually null. Also common when using Java APIs that return null for missing values.
|
|
34
|
+
- **strategy**: 1. Grep for every `!!` in the file. 2. For each `!!`, determine if null is actually possible at runtime. 3. Replace `!!` with safe alternatives: `?: throw IllegalStateException("expected non-null")`, `?: return`, or `?.let { }`. 4. For Java interop returns, use `?: error("descriptive message")` to fail with context. 5. Add `@Nullable` / `@NonNull` annotations to Java methods to improve Kotlin inference.
|
|
35
|
+
- **toolSequence**: grep (`!!`) → file_read (each occurrence) → file_edit (replace with Elvis or safe call)
|
|
36
|
+
- **pitfall**: Do NOT remove `!!` and replace with `?: null` — if the null case is logically impossible, use `?: error("message")` to make violations visible.
|
|
37
|
+
|
|
38
|
+
### Pattern: coroutine scope leak
|
|
39
|
+
|
|
40
|
+
- **symptom**: Coroutines continue running after their associated ViewModel/Fragment/Activity is destroyed. Memory grows; callbacks fire on destroyed views. `viewModelScope` or `lifecycleScope` not used properly.
|
|
41
|
+
- **cause**: Using `GlobalScope.launch` or creating a custom `CoroutineScope` without cancelling it in `onCleared()` / `onDestroy()`. The coroutine outlives the owner.
|
|
42
|
+
- **strategy**: 1. Grep for `GlobalScope.launch` and `CoroutineScope(` in the file. 2. Replace `GlobalScope.launch` with `viewModelScope.launch` in ViewModels or `lifecycleScope.launch` in Fragments/Activities. 3. For custom scopes, store the scope in a property and cancel it in the appropriate lifecycle method: `scope.cancel()` in `onCleared()`. 4. For long-running background work, use a `SupervisorJob` + explicit cancellation. 5. Use `viewModelScope` in all ViewModel coroutines — it auto-cancels on `onCleared()`.
|
|
43
|
+
- **toolSequence**: grep (`GlobalScope\|CoroutineScope(`) → file_read → file_edit (replace with viewModelScope/lifecycleScope)
|
|
44
|
+
- **pitfall**: Do NOT use `runBlocking` in production Android code on the main thread — it blocks the UI thread and causes ANRs.
|
|
45
|
+
|
|
46
|
+
### Pattern: sealed class exhaustiveness warning
|
|
47
|
+
|
|
48
|
+
- **symptom**: `'when' expression must be exhaustive, add necessary 'is SomeSubclass' branch or 'else' branch instead` — compile error when used as expression; silent miss when used as statement.
|
|
49
|
+
- **cause**: A `when` over a sealed class/interface is missing one or more subclass branches. As a statement, Kotlin allows this (no compile error), but new subclasses added to the sealed class will silently miss handling. As an expression, it is a compile error.
|
|
50
|
+
- **strategy**: 1. Read the sealed class definition to list all subclasses. 2. Add a branch for each missing subclass. 3. To enforce exhaustiveness on `when` statements (not just expressions), use a helper: define an extension property `val <T> T.exhaustive: T get() = this` and call `when (x) { ... }.exhaustive`. 4. Prefer not using `else` in sealed class when expressions — adding a new subclass should cause a compile error, not silently fall through.
|
|
51
|
+
- **toolSequence**: grep (sealed class name) → file_read (all subclasses) → file_read (when expression) → file_edit (add missing branches)
|
|
52
|
+
- **pitfall**: Do NOT add `else -> {}` to silence exhaustiveness — it defeats the purpose of sealed classes as a compile-time completeness guarantee.
|
|
53
|
+
|
|
54
|
+
### Pattern: data class copy pitfall
|
|
55
|
+
|
|
56
|
+
- **symptom**: Modifying a `data class` instance via `.copy()` but the original is still referenced elsewhere, or nested mutable objects inside a data class are shared between copies.
|
|
57
|
+
- **cause**: Kotlin's `data class` `.copy()` is a shallow copy. Nested mutable objects (e.g., `MutableList`, mutable sub-data-classes) are not deep-copied — both the original and the copy reference the same mutable object.
|
|
58
|
+
- **strategy**: 1. Read the data class definition — identify any mutable collection or mutable sub-object fields. 2. When copying, explicitly copy mutable fields: `original.copy(items = original.items.toMutableList())`. 3. Prefer immutable collections (`List`, `Map`, `Set`) in data classes and replace the whole list on update rather than mutating in place. 4. If deep copy is frequently needed, implement a `deepCopy()` extension function. 5. Use `@Immutable` annotation with Compose if used in UI state.
|
|
59
|
+
- **toolSequence**: grep (data class name) → file_read (field types) → file_read (copy usage) → file_edit (add explicit field copy for mutable fields)
|
|
60
|
+
- **pitfall**: Do NOT assume `.copy()` is a deep copy — always audit mutable nested fields after using it.
|
|
61
|
+
|
|
62
|
+
## Verification
|
|
63
|
+
Run: `./gradlew compileKotlin` or `./gradlew build`
|
|
64
|
+
- Exit 0 = no compile errors.
|
|
65
|
+
- For Android: `./gradlew assembleDebug`
|
|
66
|
+
- For lint: `./gradlew lint`
|
|
67
|
+
|
|
68
|
+
## Validation Checklist
|
|
69
|
+
- [ ] No `!!` operators without an accompanying comment proving non-null at that point
|
|
70
|
+
- [ ] No `GlobalScope.launch` — use `viewModelScope` or `lifecycleScope`
|
|
71
|
+
- [ ] All `when` on sealed classes cover every subclass explicitly (no `else` hiding new cases)
|
|
72
|
+
- [ ] `var` used only where mutation is necessary — smart cast issues resolved with `val` capture
|
|
73
|
+
- [ ] Data class mutable fields explicitly copied when using `.copy()`
|
|
74
|
+
- [ ] Coroutine scopes cancelled in lifecycle teardown (`onCleared`, `onDestroy`)
|
|
75
|
+
- [ ] `./gradlew compileKotlin` exits 0
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: lua
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.88
|
|
5
|
+
|
|
6
|
+
# Lua — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the exact error message including the file path and line number. Lua errors are often runtime-only — the interpreter does not check types or undefined variables at load time.
|
|
9
|
+
|
|
10
|
+
## Error Code Quick Reference
|
|
11
|
+
- **"attempt to index a nil value"** — Accessing a field on a nil variable or missing table key.
|
|
12
|
+
- **"attempt to call a nil value"** — Calling a function that is nil (not found or not loaded).
|
|
13
|
+
- **"attempt to perform arithmetic on a nil value"** — Math on nil variable.
|
|
14
|
+
- **"attempt to concatenate a nil value"** — String concatenation with nil.
|
|
15
|
+
- **"stack overflow"** — Infinite recursion without a base case.
|
|
16
|
+
- **"bad argument #N to 'func'"** — Wrong type passed to a built-in or type-checked function.
|
|
17
|
+
- **"table index is nil"** — Using nil as a table key: `t[nil] = value`.
|
|
18
|
+
- **"module 'x' not found"** — `require` failed; package.path doesn't include the module location.
|
|
19
|
+
|
|
20
|
+
## Known Error Patterns
|
|
21
|
+
|
|
22
|
+
### Nil Value Error — Missing Table Key
|
|
23
|
+
- **Symptom**: `attempt to index a nil value (global 'config')` or `attempt to index a nil value (field 'options')`; crash on accessing a nested field.
|
|
24
|
+
- **Cause**: A table key that was expected to exist returns `nil` in Lua — there is no KeyError, just silent nil. Chaining dot access on a nil result then causes a crash: `config.database.host` crashes if `config.database` is nil.
|
|
25
|
+
- **Strategy**: 1. Add nil guards before table access: `if config and config.database then ... end`. 2. Provide defaults with `or`: `local host = (config and config.database and config.database.host) or "localhost"`. 3. Write a safe-get helper: `local function get(t, ...) local v = t; for _, k in ipairs({...}) do if type(v) ~= "table" then return nil end; v = v[k] end; return v end`. 4. For optional config, always initialize tables with defaults before use.
|
|
26
|
+
- **Tool sequence**: file_read (nil access location) → file_edit (add nil check guards or default values)
|
|
27
|
+
- **Pitfall**: Do NOT use `pcall` to silently swallow nil errors — use it to catch errors but always log the error message for diagnosis.
|
|
28
|
+
|
|
29
|
+
### Global vs Local Variable Confusion
|
|
30
|
+
- **Symptom**: A variable modified in a function doesn't change the outer value (or unexpectedly does); different files sharing the same global name clobber each other; module-level state bleeds between tests.
|
|
31
|
+
- **Cause**: In Lua, variables are global by default unless declared with `local`. `x = 5` sets a global; `local x = 5` creates a local. A common mistake: forgetting `local` inside a function creates an unintended global that persists and conflicts.
|
|
32
|
+
- **Strategy**: 1. Declare all variables with `local` unless global access is explicitly intended. 2. Use `luacheck` to detect global variable usage: it warns on undefined globals and accidental global creation. 3. Enforce strict mode in environments that support it: `local _ENV = setmetatable({}, {__newindex = function() error("global write") end, __index = _G})`. 4. For modules, return a table of public functions instead of using globals. 5. Grep for assignments without `local` at function scope.
|
|
33
|
+
- **Tool sequence**: shell_exec (`luacheck <file.lua>`) → file_read → file_edit (add `local` keyword to variable declarations)
|
|
34
|
+
- **Pitfall**: Do NOT add `local` to a variable that is intentionally global (e.g., a registered callback that another module reads) — understand the scoping intent before adding `local`.
|
|
35
|
+
|
|
36
|
+
### 1-Based Indexing Error — Off-By-One in Arrays
|
|
37
|
+
- **Symptom**: Last element of a table is not processed; first element is skipped; `table[0]` returns nil when the array has elements.
|
|
38
|
+
- **Cause**: Lua arrays are 1-indexed by convention — `t[1]` is the first element, `t[#t]` is the last. Programmers from C, Python, or JavaScript expect 0-based indexing. `t[0]` is a valid key (Lua tables have no restriction) but it is not part of the array sequence and `#t` ignores it.
|
|
39
|
+
- **Strategy**: 1. Loops should start at `1`: `for i = 1, #t do`. 2. The last element is `t[#t]`, not `t[#t - 1]`. 3. For string operations, `string.sub(s, 1, 1)` is the first character, `string.sub(s, -1)` is the last. 4. When interfacing with C APIs that return 0-based indices, add 1 before using as a Lua table index. 5. Use `ipairs` for forward iteration over sequences — it starts at 1 and stops at the first nil.
|
|
40
|
+
- **Tool sequence**: grep (`\[0\]`, `for i = 0`) → file_read → file_edit (fix to 1-based indices)
|
|
41
|
+
- **Pitfall**: Do NOT use `pairs` where you need ordered array iteration — `pairs` has undefined order. Use `ipairs` for arrays.
|
|
42
|
+
|
|
43
|
+
### Metamethod Not Set — __index Missing for OOP
|
|
44
|
+
- **Symptom**: `attempt to index a nil value (method 'draw')` when calling a method on an "object"; the method is defined in a base class but not accessible on instances.
|
|
45
|
+
- **Cause**: Lua does not have built-in OOP. The common pattern uses metatables: `setmetatable(instance, {__index = BaseClass})`. If `__index` is not set, method lookups fall through to nil. Forgetting to call the constructor or set the metatable on instances breaks method dispatch.
|
|
46
|
+
- **Strategy**: 1. Verify the class constructor sets the metatable: `setmetatable(self, ClassName); ClassName.__index = ClassName`. 2. Check that `ClassName.__index = ClassName` is set (or `__index` points to the methods table). 3. For inheritance: `setmetatable(Child, {__index = Parent})` — missing this breaks parent method access. 4. Use a consistent OOP pattern (e.g., `middleclass`, `30log`) rather than rolling your own metamethod setup, which is error-prone.
|
|
47
|
+
- **Tool sequence**: grep (`setmetatable`, `__index`) → file_read (class definition) → file_edit (add missing __index assignment)
|
|
48
|
+
- **Pitfall**: Do NOT set `__index = self` on an instance — it should be `__index = ClassName` (the class table), not the instance itself.
|
|
49
|
+
|
|
50
|
+
### Coroutine Yield Across C Boundary
|
|
51
|
+
- **Symptom**: `attempt to yield from outside a coroutine` or `attempt to yield across a C-call boundary`; coroutine yields work in pure Lua but crash when called from C callbacks.
|
|
52
|
+
- **Cause**: When Lua is embedded in a C application (e.g., Nginx/OpenResty, game engines), some C API callbacks don't support Lua coroutine yields. The Lua C API `lua_yield` cannot be called from a C function that was itself called from a C function not designed for yielding.
|
|
53
|
+
- **Strategy**: 1. Identify which C callbacks are involved in the yield path (Nginx directives, game engine callbacks). 2. Check if the embedding environment provides coroutine-compatible APIs (e.g., OpenResty's `ngx.sleep` instead of OS sleep). 3. Use `coroutine.wrap` with `pcall` to catch yield errors gracefully. 4. Restructure to avoid yielding from within C-initiated callbacks — use event-driven callbacks instead of blocking yields. 5. Use `lua_isyieldable()` to check before yielding.
|
|
54
|
+
- **Tool sequence**: grep (`coroutine.yield`, `coroutine.resume`) → file_read → file_edit (use environment-specific non-blocking alternatives)
|
|
55
|
+
- **Pitfall**: Do NOT wrap a yield in `pcall` to suppress the error — the coroutine does not actually yield and the operation blocks. Use environment-provided async APIs.
|
|
56
|
+
|
|
57
|
+
### require Path Not Found — Module Loading Failure
|
|
58
|
+
- **Symptom**: `module 'mymodule' not found: no field package.preload['mymodule']...`; the file exists but Lua cannot find it.
|
|
59
|
+
- **Cause**: Lua searches `package.path` for modules (`.lua` files) and `package.cpath` for C modules (`.so`/`.dll`). The default path may not include the project directory. Module names use dots as separators which map to directory separators.
|
|
60
|
+
- **Strategy**: 1. Print the current path: `print(package.path)`. 2. Add the project root to the path: `package.path = package.path .. ";./?.lua;./src/?.lua"` (or set `LUA_PATH` environment variable). 3. Check module name matches file path: `require("utils.helpers")` looks for `utils/helpers.lua`. 4. For LuaRocks modules, verify installation: `luarocks list`. 5. In embedded Lua, the host application may need to set `package.path` explicitly.
|
|
61
|
+
- **Tool sequence**: shell_exec (`lua -e "print(package.path)"`) → file_read (module loading code) → file_edit (add correct path to package.path)
|
|
62
|
+
- **Pitfall**: Do NOT use absolute paths in `require()` — always use relative module paths with dots. Absolute paths are not portable.
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
Run: `luac -p <file.lua>` for syntax check, then `lua <file.lua>` for runtime.
|
|
66
|
+
- Run luacheck: `luacheck . --globals <known_globals>` — zero errors, zero warnings.
|
|
67
|
+
- Run LuaUnit or busted test suite: all tests must pass.
|
|
68
|
+
|
|
69
|
+
## Validation Checklist
|
|
70
|
+
- [ ] All variables declared with `local` unless intentionally global
|
|
71
|
+
- [ ] All table accesses guarded with nil checks or `and` short-circuit
|
|
72
|
+
- [ ] Array loops start at index `1`, not `0`
|
|
73
|
+
- [ ] All class definitions have `ClassName.__index = ClassName` set
|
|
74
|
+
- [ ] `setmetatable` called on every class instance in the constructor
|
|
75
|
+
- [ ] No coroutine yields inside C callback boundaries
|
|
76
|
+
- [ ] `require` paths use dot notation and match the actual file structure
|
|
77
|
+
- [ ] `package.path` configured correctly for the project layout
|
|
78
|
+
- [ ] luacheck passes with no undefined globals
|
|
79
|
+
- [ ] All error paths use `error()` or return `nil, error_message` — not silent nil returns
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
## Identity
|
|
2
|
+
- domain: php
|
|
3
|
+
- type: language
|
|
4
|
+
- confidence: 0.91
|
|
5
|
+
|
|
6
|
+
# PHP — Error Pattern Reference
|
|
7
|
+
|
|
8
|
+
Read the full error message including file path, line number, and error level (Notice, Warning, Fatal). PHP distinguishes levels — a Notice does not stop execution but a Fatal does.
|
|
9
|
+
|
|
10
|
+
## Error Level Quick Reference
|
|
11
|
+
- **Parse error** — Syntax error; PHP cannot compile the file.
|
|
12
|
+
- **Fatal error** — Unrecoverable; execution stops.
|
|
13
|
+
- **Warning** — Non-fatal but usually indicates a bug.
|
|
14
|
+
- **Notice** — Informational; often undefined variable or index.
|
|
15
|
+
- **Deprecated** — API usage that will be removed in a future version.
|
|
16
|
+
|
|
17
|
+
## Known Error Patterns
|
|
18
|
+
|
|
19
|
+
### Undefined variable
|
|
20
|
+
- **Symptom**: `Notice: Undefined variable: foo` or in PHP 8: `Warning: Undefined variable $foo`
|
|
21
|
+
- **Cause**: Using a variable that has not been assigned in the current scope. Common when a conditional assignment is skipped or a parameter name is misspelled.
|
|
22
|
+
- **Strategy**: 1. Read the function or scope where the variable is used. 2. Trace all code paths — is there a branch where the variable is never set? 3. Add a default assignment before the conditional: `$foo = null;` or `$foo = [];`. 4. For superglobals (`$_GET`, `$_POST`), use `isset` or `??`: `$val = $_GET['key'] ?? null`.
|
|
23
|
+
- **Tool sequence**: file_read (function scope) → grep (all assignments to variable) → file_edit (add default assignment)
|
|
24
|
+
- **Pitfall**: Do NOT suppress with `@` operator. Fix the missing assignment.
|
|
25
|
+
|
|
26
|
+
### Call to undefined function
|
|
27
|
+
- **Symptom**: `Fatal error: Call to undefined function foo()`
|
|
28
|
+
- **Cause**: Function not defined in scope. Missing `require`/`include` for the file containing it, missing Composer autoload, or a misspelled function name.
|
|
29
|
+
- **Strategy**: 1. Grep for the function definition across the project. 2. If found, check whether the file containing it is required at the call site. 3. If it is a Composer package function, verify `require 'vendor/autoload.php'` is present at the entry point. 4. Check PHP extension functions — the required extension may not be loaded (check `php.ini` with `phpinfo()`).
|
|
30
|
+
- **Tool sequence**: grep (`function foo`) → file_read (entry point for autoload) → shell_exec (`php -m` for extensions)
|
|
31
|
+
- **Pitfall**: Do NOT copy-paste the function definition inline. Find the canonical source and require it properly.
|
|
32
|
+
|
|
33
|
+
### Cannot use object of type stdClass as array
|
|
34
|
+
- **Symptom**: `Fatal error: Cannot use object of type stdClass as array`
|
|
35
|
+
- **Cause**: `json_decode()` without the second argument returns an `stdClass` object, not an array. Accessing it with `$result['key']` fails; `$result->key` is required.
|
|
36
|
+
- **Strategy**: 1. Find the `json_decode` call. 2. Pass `true` as the second argument to return an associative array: `json_decode($json, true)`. 3. If the type needs to be `stdClass` in some places, use object notation consistently: `$result->key`.
|
|
37
|
+
- **Tool sequence**: grep (`json_decode`) → file_read → file_edit (add second argument `true`)
|
|
38
|
+
- **Pitfall**: Do NOT cast `(array)` on nested objects — it only shallowly converts the top level.
|
|
39
|
+
|
|
40
|
+
### Type juggling bug: == vs ===
|
|
41
|
+
- **Symptom**: Comparisons return unexpected truthy/falsy results. E.g., `"0" == false` is true, `"1" == true` is true, `0 == "foo"` is true (PHP < 8), `"1" == "01"` is true.
|
|
42
|
+
- **Cause**: PHP's loose comparison (`==`) coerces types. This causes subtle bugs in password comparison, status checks, and array search results.
|
|
43
|
+
- **Strategy**: 1. Grep all `==` comparisons involving variables that could be mixed types (strings from user input, database fields, `in_array` calls). 2. Replace with strict `===` wherever type equality must be enforced. 3. For `in_array`, pass `true` as the third argument: `in_array($val, $arr, true)`.
|
|
44
|
+
- **Tool sequence**: grep (`==\s`) → file_read (comparison context) → file_edit (replace with `===`)
|
|
45
|
+
- **Pitfall**: Do NOT globally replace all `==` with `===` — some intentional type-coercing comparisons may exist. Review each case.
|
|
46
|
+
|
|
47
|
+
### Composer autoload not loaded
|
|
48
|
+
- **Symptom**: `Fatal error: Class 'Vendor\Package\Foo' not found` even though the package is in `composer.json`
|
|
49
|
+
- **Cause**: `require_once __DIR__ . '/vendor/autoload.php';` is missing from the entry point, or the dependencies were not installed (`vendor/` directory absent).
|
|
50
|
+
- **Strategy**: 1. Check the entry point file (usually `index.php`, `bootstrap.php`, or the framework entry). 2. Verify `require_once __DIR__ . '/vendor/autoload.php';` is the first require. 3. Run `composer install` if `vendor/` is missing. 4. If using a namespace, verify `composer.json` has the correct `autoload.psr-4` mapping and run `composer dump-autoload`.
|
|
51
|
+
- **Tool sequence**: file_read (entry point) → shell_exec (`ls vendor/`) → shell_exec (`composer install` or `composer dump-autoload`)
|
|
52
|
+
- **Pitfall**: Do NOT manually add `require` statements for individual Composer classes. Fix the autoload setup.
|
|
53
|
+
|
|
54
|
+
### Undefined array key / index
|
|
55
|
+
- **Symptom**: `Warning: Undefined array key "foo"` or `Notice: Undefined index: foo`
|
|
56
|
+
- **Cause**: Accessing an array key that does not exist. Common with form inputs, API responses, or optional config keys.
|
|
57
|
+
- **Strategy**: 1. Use `isset($arr['key'])` or the null coalescing operator `$arr['key'] ?? null` before accessing. 2. For required keys, throw an explicit exception or return an error rather than silently returning null.
|
|
58
|
+
- **Tool sequence**: file_read (array access line) → file_edit (add `isset` check or `??` operator)
|
|
59
|
+
- **Pitfall**: Do NOT use `@$arr['key']` to suppress the warning. Use `??` or `isset`.
|
|
60
|
+
|
|
61
|
+
## Verification
|
|
62
|
+
Run: `php -l <file>` for syntax check.
|
|
63
|
+
- For full project: `./vendor/bin/phpstan analyse` (if PHPStan is configured) or `./vendor/bin/psalm`.
|
|
64
|
+
- Always run `composer install` before testing if `vendor/` is absent or stale.
|
|
65
|
+
|
|
66
|
+
## Validation Checklist
|
|
67
|
+
- [ ] `php -l` exits 0 for all modified files
|
|
68
|
+
- [ ] All `json_decode` calls pass `true` as second arg when array access is used
|
|
69
|
+
- [ ] All security-sensitive comparisons use `===` not `==`
|
|
70
|
+
- [ ] `require_once __DIR__ . '/vendor/autoload.php'` present in entry point
|
|
71
|
+
- [ ] No `@` error suppression operator added
|
|
72
|
+
- [ ] All `$_GET`/`$_POST`/`$_REQUEST` accesses use `??` or `isset`
|
|
73
|
+
- [ ] `in_array` calls use strict mode (`true` as third argument) for type-sensitive checks
|