{"record":{"id":"c078faffc0fd540a","repo":"jackwener/OpenCLI","slug":"openreview-api-error-for-label-detail","errorCode":null,"errorMessage":"OpenReview API error for ${label}: ${detail}","messagePattern":"OpenReview API error for (.+?): (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/openreview/utils.js","lineNumber":105,"sourceCode":"        try { body = (await resp.text()).slice(0, 200); } catch {}\n        throw new CommandExecutionError(`OpenReview API HTTP ${resp.status} for ${label}${body ? ` (${body})` : ''}`, 'The OpenReview API may be down or rate-limiting.');\n    }\n    let json;\n    try {\n        json = await resp.json();\n    }\n    catch (e) {\n        throw new CommandExecutionError(`Malformed JSON from OpenReview for ${label}: ${e?.message ?? e}`, 'Try again or report this as an OpenReview API bug.');\n    }\n    const envelopeErrors = Array.isArray(json?.errors) ? json.errors.filter(Boolean) : [];\n    const envelopeError = typeof json?.error === 'string' ? json.error.trim() : '';\n    if (envelopeErrors.length || envelopeError) {\n        const detail = envelopeError || envelopeErrors.map((entry) => {\n            if (typeof entry === 'string') return entry;\n            if (entry?.message) return String(entry.message);\n            return JSON.stringify(entry);\n        }).join('; ');\n        throw new CommandExecutionError(`OpenReview API error for ${label}: ${detail}`, 'The OpenReview API returned an application-level error.');\n    }\n    return json;\n}\n\n/** Format ms-since-epoch as YYYY-MM-DD; empty string for invalid input. */\nexport function formatDate(ms) {\n    if (typeof ms !== 'number' || !Number.isFinite(ms) || ms <= 0) return '';\n    return new Date(ms).toISOString().slice(0, 10);\n}\n\n/** Read a v2 content field, which is wrapped as `{ value: ... }`. */\nexport function readContent(content, key) {\n    const v = content?.[key]?.value;\n    if (v === undefined || v === null) return undefined;\n    return v;\n}\n\n/** Build an absolute PDF URL from the `content.pdf` value, which may be a relative `/pdf/<hash>.pdf`. */","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/openreview/utils.js#L87-L123","documentation":"openreviewFetch throws CommandExecutionError when the API responds 200 but its JSON envelope carries an application-level error (json.errors array or json.error string). The per-entry messages are stringified and joined into 'detail'. This surfaces OpenReview's own error semantics rather than hiding them as empty data.","triggerScenarios":"The OpenReview API returns {error: ...} or {errors: [...]} in the body, e.g. for a malformed invitation id, an unknown forum on certain endpoints, or API-side validation failures.","commonSituations":"Querying an invitation id that no longer exists (venue renamed, e.g. old year paths); API v1 vs v2 endpoint mismatch for the given id; OpenReview rejecting a query parameter combination.","solutions":["Read 'detail' in the message — it states the API's own reason.","Verify the forum/invitation id is current; re-check on openreview.net (venues change year to year).","Ensure you are hitting the correct API version (api2) for 2023+ venues."],"exampleFix":"// before\nconst json = await openreviewFetch(`/notes?forum=${id}`, label);\n// after\ntry { var json = await openreviewFetch(`/notes?forum=${id}`, label); }\ncatch (e) { if (/API error/.test(e.message)) { console.error('check the id:', id); } throw e; }","handlingStrategy":"try-catch","validationCode":"// verify ids look current before querying\nif (!/^[A-Za-z0-9_-]{6,20}$/.test(forumId)) throw new Error('bad forum id');\nif (invitationId && !invitationId.includes('/-/')) throw new Error('bad invitation id');","typeGuard":null,"tryCatchPattern":"try { const json = await openreviewFetch(path, label); }\ncatch (e) { if (/OpenReview API error/.test(e.message)) { console.error(e.message, '— verify the id on openreview.net'); process.exit(1); } throw e; }","preventionTips":["Read the 'detail' portion of the message — it is the API's own explanation.","Re-verify venue/invitation ids each year on openreview.net.","Use the api2 endpoints for 2023+ venues.","Catch CommandExecutionError explicitly, not bare Error."],"tags":["api-error","openreview","envelope-error"],"backgroundTag":"api-application-error","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}