{"record":{"id":"1683ec8e529152c1","repo":"jackwener/OpenCLI","slug":"unknown-graphql-error","errorCode":null,"errorMessage":"Unknown GraphQL error","messagePattern":"Unknown GraphQL error","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/lesswrong/_helpers.js","lineNumber":21,"sourceCode":"export const DOMAIN = 'www.lesswrong.com';\nconst GRAPHQL_URL = `https://${DOMAIN}/graphql`;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- GraphQL responses vary per query\nexport async function gqlRequest(query) {\n    const resp = await fetch(GRAPHQL_URL, {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/json',\n            Accept: 'application/json',\n        },\n        body: JSON.stringify({ query }),\n        signal: AbortSignal.timeout(15000),\n    });\n    if (!resp.ok) {\n        throw new CommandExecutionError(`LessWrong API returned HTTP ${resp.status}`);\n    }\n    const json = (await resp.json());\n    if (json.errors?.length) {\n        throw new CommandExecutionError(json.errors[0]?.message ?? 'Unknown GraphQL error');\n    }\n    return json.data;\n}\nexport function gqlEscape(str) {\n    return str.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\nexport function stripHtml(html) {\n    if (!html)\n        return '';\n    return html\n        .replace(/<script[^>]*>.*?<\\/script>/gis, ' ')\n        .replace(/<style[^>]*>.*?<\\/style>/gis, ' ')\n        .replace(/<[^>]+>/g, ' ')\n        .replace(/\\s+/g, ' ')\n        .trim();\n}\nexport function daysAgo(n) {\n    const d = new Date();","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/lesswrong/_helpers.js#L3-L39","documentation":"After a successful HTTP response, gqlRequest checks json.errors, the standard GraphQL error channel. If the endpoint returned errors array entries, the first error's message is thrown; the literal 'Unknown GraphQL error' appears when the first error object has no message. This signals query-level failures (bad fields, syntax, auth) rather than transport issues.","triggerScenarios":"The GraphQL query references a nonexistent field/type, has a syntax error, requests an unauthenticated field, or LessWrong returns errors:[{}] with no message text.","commonSituations":"LessWrong GraphQL schema changed or a field was renamed (e.g. old queries using removed fields); dynamically built query strings with malformed interpolation; internal resolver error returned without a message.","solutions":["Inspect the query string for invalid/renamed fields and test it in the LessWrong GraphQL playground (lesswrong.com/graphql)","Rebuild the query from the current LessWrong GraphQL schema","Check gqlEscape usage when interpolating user strings to avoid query syntax errors","If errors:[{message:null}], log json.errors fully to see the underlying code/extensions"],"exampleFix":"// before\nconst query = `query { user(input: {selector: {slug: \"${slug}\"}}) { result { _id } } }`;\n// after\nconst query = `query { user(input: {selector: {slug: \"${gqlEscape(slug)}\"}}) { result { _id } } }`;","handlingStrategy":"type-guard","validationCode":"// validate interpolated values before building the query\nif (!/^[a-z0-9-]*$/.test(slug)) throw new Error('invalid slug for query');","typeGuard":"const hasGraphqlErrors = (json) => Array.isArray(json?.errors) && json.errors.length > 0;","tryCatchPattern":"try {\n  const data = await gqlRequest(query);\n} catch (e) {\n  if (String(e.message) === 'Unknown GraphQL error' || /GraphQL/i.test(e.message)) {\n    console.error('GraphQL query failed — validate fields against current LessWrong schema');\n  } else throw e;\n}","preventionTips":["Keep queries in sync with the current LessWrong GraphQL schema","Always gqlEscape interpolated strings","Test queries in the LessWrong GraphQL playground first","Log full json.errors when messages are missing"],"tags":["graphql","query-error","lesswrong","schema"],"backgroundTag":"graphql-error-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}