{"id":"cb2ea277-9b42-43ae-802f-0197ae487513","shortId":"EqfZfy","kind":"skill","title":"Edge Case Discovery","tagline":"Systematically identifies edge cases and boundary conditions for any function, API, or user flow.","description":"# Edge Case Discovery\n\n## What this skill does\n\nThis skill directs the agent to systematically work through a function, API endpoint, or user flow and enumerate all edge cases and boundary conditions that could cause incorrect behavior, errors, or security issues. It applies a structured checklist across multiple dimensions (data types, boundary values, state, concurrency, authorization) and outputs a prioritized list of cases to test or guard against.\n\nUse this before writing tests, during code review, when designing a new feature, or when a production bug makes you wonder \"what else could go wrong here.\"\n\n## How to use\n\n### Claude Code / Cline\n\nCopy this file to `.agents/skills/edge-case-discovery/SKILL.md` in your project root.\n\nThen ask:\n- *\"Use the Edge Case Discovery skill on the `transferFunds` function.\"*\n- *\"Find edge cases for the `POST /api/orders` endpoint using the Edge Case Discovery skill.\"*\n- *\"What edge cases should I handle in the user registration flow? Use the Edge Case Discovery skill.\"*\n\nProvide the function signature, the code, or a description of the flow.\n\n### Cursor\n\nAdd the instructions below to your `.cursorrules` or paste them into the Cursor AI pane before sharing the function or flow you want analyzed.\n\n### Codex\n\nPaste the function or flow description and ask Codex to follow the instructions below to generate the edge case list.\n\n## The Prompt / Instructions for the Agent\n\nWhen asked to discover edge cases, apply the following checklist systematically. Not every dimension applies to every input — skip the ones that clearly don't apply and note why.\n\n### Dimension 1 — Numeric inputs\n\nFor every numeric input or value in the function/flow:\n- Zero (0)\n- Negative numbers\n- Maximum safe integer / maximum allowed value\n- Minimum allowed value\n- Values just above and just below each boundary (boundary value analysis)\n- Non-integer values when integers are expected\n- Infinity / NaN (for floating-point)\n- Very large numbers that could cause overflow or performance issues\n\n### Dimension 2 — String inputs\n\nFor every string input:\n- Empty string (`\"\"`)\n- Whitespace-only string (`\" \"`, `\"\\t\"`, `\"\\n\"`)\n- Maximum length string (at or beyond any length limit)\n- Single character\n- Unicode characters (emoji, RTL text, accented characters)\n- SQL injection payloads: `' OR 1=1 --`\n- XSS payloads: `<script>alert(1)</script>`\n- Null bytes and control characters\n- Strings that look like other types: `\"null\"`, `\"undefined\"`, `\"true\"`, `\"123\"`\n\n### Dimension 3 — Collections (arrays, lists, maps)\n\nFor every collection input:\n- Empty collection (`[]`, `{}`)\n- Single item\n- Very large collection (performance/timeout risk)\n- Duplicate items (if uniqueness is expected)\n- Items in unexpected order\n- Null or undefined items within the collection\n- Collection with all identical values\n\n### Dimension 4 — Null and missing values\n\n- `null` where an object is expected\n- `undefined` where a value is expected\n- Missing optional fields in a request body\n- Fields present but set to `null` explicitly\n- Partially populated objects (some required fields missing)\n\n### Dimension 5 — State and ordering\n\n- Running the operation twice (idempotency: does it produce duplicates?)\n- Running the operation on already-completed state (e.g., canceling a canceled order)\n- Running operations out of expected order\n- Concurrent calls (two users doing the same operation at the same time)\n- Calling a cleanup/delete before the resource is fully initialized\n- Interrupted operations (what happens if the process crashes halfway?)\n\n### Dimension 6 — Authorization and ownership\n\n- Accessing a resource belonging to another user\n- Accessing a deleted or expired resource\n- Using an expired or revoked token\n- Accessing with insufficient permissions (role too low)\n- Accessing with no authentication at all\n- Privilege escalation attempts (passing someone else's ID in the request body)\n\n### Dimension 7 — External dependencies\n\n- Third-party API returns an error\n- Third-party API times out\n- Third-party API returns an unexpected response shape\n- Database is unavailable or returns a constraint violation\n- File system is full or read-only\n\n### Format the output\n\n```markdown\n## Edge Cases for [Function/Endpoint/Flow]\n\n### Critical (must handle — will cause data loss, security issue, or crash)\n1. [Edge case] — [Why it's critical] — [What currently happens / what should happen]\n\n### High (should handle — causes incorrect behavior or poor UX)\n1. [Edge case] — [Expected behavior]\n\n### Medium (nice to handle — minor issues or uncommon paths)\n1. [Edge case] — [Expected behavior]\n\n### Out of scope / acceptable to ignore\n1. [Edge case] — [Why it's acceptable to not handle]\n\n### Suggested test cases\n[List the top 5–7 cases to write as unit/integration tests, in order of priority]\n```\n\n## Example\n\n**Input to Agent:**\n> \"Use the Edge Case Discovery skill on this function:\n> ```ts\n> async function transferFunds(fromAccountId: string, toAccountId: string, amount: number) {\n>   const from = await Account.findById(fromAccountId);\n>   const to = await Account.findById(toAccountId);\n>   from.balance -= amount;\n>   to.balance += amount;\n>   await from.save();\n>   await to.save();\n> }\n> ```\"\n\n**Output from Agent:**\n\n> ## Edge Cases for `transferFunds`\n>\n> ### Critical\n> 1. **`amount` is negative** — Caller passes `-100`, which silently reverses the transfer direction. Should throw a validation error.\n> 2. **`fromAccountId === toAccountId`** — Transferring to the same account: balance unchanged but operation succeeds silently. May indicate a bug in the caller.\n> 3. **Insufficient balance** — `from.balance` goes negative. No guard exists. Should check balance before deducting.\n> 4. **Race condition on concurrent transfers** — Two simultaneous transfers from the same account can both read the same balance and both succeed, causing a negative balance. Requires a database transaction with row-level locking.\n> 5. **`from.save()` succeeds but `to.save()` fails** — Money is deducted from sender but never credited to receiver. The whole operation must be wrapped in a database transaction that rolls back on failure.\n>\n> ### High\n> 6. **`fromAccountId` or `toAccountId` not found** — `Account.findById` returns `null`, and `from.balance` throws `Cannot read properties of null`. Add existence checks.\n> 7. **`amount` is `0`** — Technically valid but likely a bug in the caller. Consider throwing a validation error.\n> 8. **`amount` is `Infinity` or `NaN`** — JavaScript will not throw; balance becomes `Infinity` or `NaN` silently.\n>\n> ### Suggested test cases\n> 1. Transfer with insufficient balance → expect error thrown, balances unchanged\n> 2. Transfer to self → expect error thrown\n> 3. Transfer with negative amount → expect validation error\n> 4. Either account not found → expect error thrown, no balance changes\n> 5. `to.save()` throws → expect `from` balance is rolled back\n\n## Notes\n\n- Run this skill before writing tests, not after — it's faster to discover edge cases analytically than by writing tests and waiting for them to fail.\n- For APIs, always run Dimension 6 (authorization) — authorization edge cases are the most commonly missed and the most dangerous.\n- Not every edge case needs a test — some can be handled with a single defensive guard at the function boundary.","tags":["edge","case","discovery","openagentskills","notysoty","agent-skills","claude","claude-code","claude-skills","cline","cursor","llm"],"capabilities":["skill","source-notysoty","skill-edge-case-discovery","topic-agent-skills","topic-claude","topic-claude-code","topic-claude-skills","topic-cline","topic-cursor","topic-llm","topic-llm-skills","topic-skills"],"categories":["openagentskills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/Notysoty/openagentskills/edge-case-discovery","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add Notysoty/openagentskills","source_repo":"https://github.com/Notysoty/openagentskills","install_from":"skills.sh"}},"qualityScore":"0.454","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 8 github stars · SKILL.md body (7,326 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:13:21.477Z","embedding":null,"createdAt":"2026-05-18T13:20:42.293Z","updatedAt":"2026-05-18T19:13:21.477Z","lastSeenAt":"2026-05-18T19:13:21.477Z","tsv":"'-100':764 '/api/orders':145 '0':277,901 '1':264,362,363,634,656,670,681,758,935 '123':380 '2':325,776,945 '3':382,797,952 '4':423,811,960 '5':462,697,846,971 '6':525,878,1012 '7':574,698,898 '8':916 'accent':356 'accept':678,687 'access':529,536,548,555 'account':783,823,962 'account.findbyid':735,740,884 'across':63 'add':183,895 'agent':29,233,712,752 'agents/skills/edge-case-discovery/skill.md':122 'ai':196 'allow':284,287 'alreadi':480 'already-complet':479 'alway':1009 'amount':730,743,745,759,899,917,956 'analysi':299 'analyt':996 'analyz':206 'anoth':534 'api':14,36,580,587,593,1008 'appli':59,240,248,259 'array':384 'ask':128,215,235 'async':723 'attempt':563 'authent':558 'author':72,526,1013,1014 'await':734,739,746,748 'back':874,979 'balanc':784,799,808,829,836,926,939,943,969,976 'becom':927 'behavior':53,652,660,674 'belong':532 'beyond':345 'bodi':446,572 'boundari':9,47,68,296,297,1045 'bug':102,793,907 'byte':367 'call':495,506 'caller':762,796,910 'cancel':484,486 'cannot':890 'case':2,7,19,45,79,132,141,150,155,167,226,239,620,636,658,672,683,693,699,716,754,934,995,1016,1029 'caus':51,319,627,650,833 'chang':970 'charact':350,352,357,370 'check':807,897 'checklist':62,243 'claud':115 'cleanup/delete':508 'clear':256 'cline':117 'code':91,116,175 'codex':207,216 'collect':383,389,392,397,416,417 'common':1020 'complet':481 'concurr':71,494,815 'condit':10,48,813 'consid':911 'const':732,737 'constraint':605 'control':369 'copi':118 'could':50,108,318 'crash':522,633 'credit':859 'critic':623,640,757 'current':642 'cursor':182,195 'cursorrul':189 'danger':1025 'data':66,628 'databas':599,839,870 'deduct':810,854 'defens':1040 'delet':538 'depend':576 'descript':178,213 'design':94 'dimens':65,247,263,324,381,422,461,524,573,1011 'direct':27,770 'discov':237,993 'discoveri':3,20,133,151,168,717 'duplic':400,474 'e.g':483 'edg':1,6,18,44,131,140,149,154,166,225,238,619,635,657,671,682,715,753,994,1015,1028 'either':961 'els':107,566 'emoji':353 'empti':332,391 'endpoint':37,146 'enumer':42 'error':54,583,775,915,941,950,959,966 'escal':562 'everi':246,250,268,329,388,1027 'exampl':709 'exist':805,896 'expect':307,405,433,439,492,659,673,940,949,957,965,974 'expir':540,544 'explicit':453 'extern':575 'fail':851,1006 'failur':876 'faster':991 'featur':97 'field':442,447,459 'file':120,607 'find':139 'float':312 'floating-point':311 'flow':17,40,163,181,203,212 'follow':218,242 'format':615 'found':883,964 'from.balance':742,800,888 'from.save':747,847 'fromaccountid':726,736,777,879 'full':610 'fulli':513 'function':13,35,138,172,201,210,721,724,1044 'function/endpoint/flow':622 'function/flow':275 'generat':223 'go':109 'goe':801 'guard':83,804,1041 'halfway':523 'handl':158,625,649,664,690,1036 'happen':518,643,646 'high':647,877 'id':568 'idempot':470 'ident':420 'identifi':5 'ignor':680 'incorrect':52,651 'indic':791 'infin':308,919,928 'initi':514 'inject':359 'input':251,266,270,327,331,390,710 'instruct':185,220,230 'insuffici':550,798,938 'integ':282,302,305 'interrupt':515 'issu':57,323,631,666 'item':394,401,406,413 'javascript':922 'larg':315,396 'length':341,347 'level':844 'like':374,905 'limit':348 'list':77,227,385,694 'lock':845 'look':373 'loss':629 'low':554 'make':103 'map':386 'markdown':618 'maximum':280,283,340 'may':790 'medium':661 'minimum':286 'minor':665 'miss':426,440,460,1021 'money':852 'multipl':64 'must':624,865 'n':339 'nan':309,921,930 'need':1030 'negat':278,761,802,835,955 'never':858 'new':96 'nice':662 'non':301 'non-integ':300 'note':261,980 'null':366,377,410,424,428,452,886,894 'number':279,316,731 'numer':265,269 'object':431,456 'one':254 'oper':468,477,489,501,516,787,864 'option':441 'order':409,465,487,493,706 'output':74,617,750 'overflow':320 'ownership':528 'pane':197 'parti':579,586,592 'partial':454 'pass':564,763 'past':191,208 'path':669 'payload':360,365 'perform':322 'performance/timeout':398 'permiss':551 'point':313 'poor':654 'popul':455 'post':144 'present':448 'priorit':76 'prioriti':708 'privileg':561 'process':521 'produc':473 'product':101 'project':125 'prompt':229 'properti':892 'provid':170 'race':812 'read':613,826,891 'read-on':612 'receiv':861 'registr':162 'request':445,571 'requir':458,837 'resourc':511,531,541 'respons':597 'return':581,594,603,885 'revers':767 'review':92 'revok':546 'risk':399 'role':552 'roll':873,978 'root':126 'row':843 'row-level':842 'rtl':354 'run':466,475,488,981,1010 'safe':281 'scope':677 'secur':56,630 'self':948 'sender':856 'set':450 'shape':598 'share':199 'signatur':173 'silent':766,789,931 'simultan':818 'singl':349,393,1039 'skill':23,26,134,152,169,718,983 'skill-edge-case-discovery' 'skip':252 'someon':565 'source-notysoty' 'sql':358 'state':70,463,482 'string':326,330,333,337,342,371,727,729 'structur':61 'succeed':788,832,848 'suggest':691,932 'system':608 'systemat':4,31,244 'technic':902 'test':81,89,692,704,933,986,1000,1032 'text':355 'third':578,585,591 'third-parti':577,584,590 'throw':772,889,912,925,973 'thrown':942,951,967 'time':505,588 'to.balance':744 'to.save':749,850,972 'toaccountid':728,741,778,881 'token':547 'top':696 'topic-agent-skills' 'topic-claude' 'topic-claude-code' 'topic-claude-skills' 'topic-cline' 'topic-cursor' 'topic-llm' 'topic-llm-skills' 'topic-skills' 'transact':840,871 'transfer':769,779,816,819,936,946,953 'transferfund':137,725,756 'true':379 'ts':722 'twice':469 'two':496,817 'type':67,376 'unavail':601 'unchang':785,944 'uncommon':668 'undefin':378,412,434 'unexpect':408,596 'unicod':351 'uniqu':403 'unit/integration':703 'use':85,114,129,147,164,542,713 'user':16,39,161,497,535 'ux':655 'valid':774,903,914,958 'valu':69,272,285,288,289,298,303,421,427,437 'violat':606 'wait':1002 'want':205 'whitespac':335 'whitespace-on':334 'whole':863 'within':414 'wonder':105 'work':32 'wrap':867 'write':88,701,985,999 'wrong':110 'xss':364 'zero':276","prices":[{"id":"af073e0f-866c-4537-8dfb-bddc84bebcc0","listingId":"cb2ea277-9b42-43ae-802f-0197ae487513","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"Notysoty","category":"openagentskills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:20:42.293Z"}],"sources":[{"listingId":"cb2ea277-9b42-43ae-802f-0197ae487513","source":"github","sourceId":"Notysoty/openagentskills/edge-case-discovery","sourceUrl":"https://github.com/Notysoty/openagentskills/tree/main/skills/edge-case-discovery","isPrimary":false,"firstSeenAt":"2026-05-18T13:20:42.293Z","lastSeenAt":"2026-05-18T19:13:21.477Z"}],"details":{"listingId":"cb2ea277-9b42-43ae-802f-0197ae487513","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"Notysoty","slug":"edge-case-discovery","github":{"repo":"Notysoty/openagentskills","stars":8,"topics":["agent-skills","claude","claude-code","claude-skills","cline","cursor","llm","llm-skills","skills"],"license":"mit","html_url":"https://github.com/Notysoty/openagentskills","pushed_at":"2026-03-28T06:50:19Z","description":"A  community-driven library of reusable AI agent skills for Claude Code, Cursor, Codex, Cline, and more.","skill_md_sha":"cddbea71fb71331fa77615beab01be1cf09050cf","skill_md_path":"skills/edge-case-discovery/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/Notysoty/openagentskills/tree/main/skills/edge-case-discovery"},"layout":"multi","source":"github","category":"openagentskills","frontmatter":{"name":"Edge Case Discovery","description":"Systematically identifies edge cases and boundary conditions for any function, API, or user flow."},"skills_sh_url":"https://skills.sh/Notysoty/openagentskills/edge-case-discovery"},"updatedAt":"2026-05-18T19:13:21.477Z"}}