{"record":{"id":"398c6914018a850d","repo":"sickn33/agentic-awesome-skills","slug":"invalid-json-error","errorCode":null,"errorMessage":"Invalid JSON: ${error}","messagePattern":"Invalid JSON: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skills/fp-refactor/SKILL.md","lineNumber":62,"sourceCode":"\n### The Problem with try-catch\n\nTraditional try-catch blocks have several issues:\n- Error handling is implicit and easy to forget\n- The type system doesn't track which functions can throw\n- Control flow is non-linear and harder to reason about\n- Composing multiple fallible operations is verbose\n\n### Pattern: Synchronous try-catch to Either\n\n#### Before (Imperative)\n\n```typescript\nfunction parseJSON(input: string): unknown {\n  try {\n    return JSON.parse(input);\n  } catch (error) {\n    throw new Error(`Invalid JSON: ${error}`);\n  }\n}\n\nfunction validateUser(data: unknown): User {\n  try {\n    if (!data || typeof data !== 'object') {\n      throw new Error('Data must be an object');\n    }\n    const obj = data as Record<string, unknown>;\n    if (typeof obj.name !== 'string') {\n      throw new Error('Name is required');\n    }\n    if (typeof obj.age !== 'number') {\n      throw new Error('Age must be a number');\n    }\n    return { name: obj.name, age: obj.age };\n  } catch (error) {\n    throw error;","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/sickn33/agentic-awesome-skills/blob/58d857988fcfac6986206bca2b2fe223aa437e4b/skills/fp-refactor/SKILL.md#L44-L80","documentation":"In the fp-refactor skill's before-code, parseJSON catches JSON.parse's SyntaxError and re-wraps it with the 'Invalid JSON' prefix. It fires whenever the input string is not well-formed JSON — the skill uses it to motivate error-as-value refactoring.","triggerScenarios":"Calling parseJSON with truncated payloads, single quotes, trailing commas, unquoted keys, plain text/HTML error pages from an API, or an empty string.","commonSituations":"APIs returning HTML error pages with 200 status; truncated responses from cut connections; log lines with JSON-ish prefixes; hand-built strings missing quotes.","solutions":["Log the offending substring around the parse position to find the malformed token","If APIs may return HTML error pages, check content-type before parsing","Return E.Either<Error, unknown> from parseJSON instead of throwing (the skill's refactor direction)"],"exampleFix":"// before\ntry { return JSON.parse(input) } catch (e) { throw new Error(`Invalid JSON: ${e}`) }\n\n// after\nconst parseJSON = (input: string): E.Either<Error, unknown> =>\n  E.tryCatch(() => JSON.parse(input), E.toError)","handlingStrategy":"validation","validationCode":"const looksLikeJson = (s: string) => /^\\s*[\\[\\{\"\\d-tnf]/.test(s)","typeGuard":null,"tryCatchPattern":"try {\n  JSON.parse(input)\n} catch (e) {\n  // e is SyntaxError with position info; log input around e.message\n}","preventionTips":["Check content-type before parsing API responses","Validate untrusted strings with a schema-aware parser at the edge"],"tags":["json","parsing","validation"],"backgroundTag":"json-parse-error","analyzedSha":"58d857988fcfac6986206bca2b2fe223aa437e4b","analyzedAt":"2026-08-26T11:55:59.350Z","schemaVersion":2},"datasetVersion":"2026-08-26T14:46:13.012Z"}