{"record":{"id":"675d952a4304c47d","repo":"jackwener/OpenCLI","slug":"devto-id","errorCode":null,"errorMessage":"devto/${id}","messagePattern":"devto/(.+?)","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"error","filePath":"clis/devto/read.js","lineNumber":77,"sourceCode":"    description: 'Read a DEV.to article body by id',\n    domain: 'dev.to',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [\n        { name: 'id', required: true, positional: true, help: 'DEV.to article id (numeric, e.g. 3605688)' },\n        { name: 'max-length', type: 'int', default: 20000, help: 'Max characters of body to return (min 100)' },\n    ],\n    columns: ['id', 'title', 'author', 'reactions', 'reading_time', 'tags', 'published_at', 'body', 'url'],\n    func: async (args) => {\n        const id = String(args.id || '').trim();\n        if (!/^\\d+$/.test(id)) {\n            throw new ArgumentError(`Invalid DEV.to article id: ${args.id}`, 'Pass a numeric id like 3605688');\n        }\n        const maxLength = requireMinInt(args['max-length'] ?? 20000, 100, 'devto read --max-length');\n\n        const article = await fetchArticle(id);\n        if (!article || !article.id) {\n            throw new EmptyResultError(`devto/${id}`, 'Article not found');\n        }\n\n        const body = requireArticleBody(article, id);\n        const truncated = body.length > maxLength\n            ? body.slice(0, maxLength) + '\\n\\n... [truncated]'\n            : body;\n\n        // The single-article endpoint returns `tag_list` as a comma-separated\n        // string and `tags` as an array — the opposite of the listing endpoints.\n        // Normalize either shape into a single comma-separated string.\n        const tagsRaw = article.tag_list ?? article.tags ?? '';\n        const tags = Array.isArray(tagsRaw) ? tagsRaw.join(', ') : String(tagsRaw);\n\n        return [{\n            id: article.id,\n            title: article.title || '',\n            author: article.user?.username || '[deleted]',\n            reactions: article.public_reactions_count ?? 0,","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/devto/read.js#L59-L95","documentation":"EmptyResultError is thrown by `devto read` when the DEV.to API responds successfully but returns no article object for the requested id (fetchArticle returned null/undefined or an object lacking an `id`). The library treats an unidentifiable article as an empty result rather than a crash. It means the id was numeric/format-valid but the article does not exist or is not visible.","triggerScenarios":"Running `devto read <numericId>` where the id does not correspond to any published article, the article was deleted/unpublished, or the API request failed silently and returned an empty body.","commonSituations":"Typo in a copied article id; article taken down by its author; DEV.to API returning an error object or empty payload (rate limiting, private/hidden content) that fetchArticle maps to null.","solutions":["Verify the id is a real published DEV.to article (open dev.to and confirm the URL /<author>/<slug> maps to that id).","Re-run the command to rule out a transient API failure, and check DEV.to API availability/rate limits.","If you scraped the id earlier, re-fetch the article list to get the current id (deleted articles keep their id forever unreachable).","Call the DEV.to API directly (curl https://dev.to/api/articles/<id>) to confirm it 404s before debugging the CLI."],"exampleFix":"// before\nawait cli.devto.read({ id: 3605688 });\n// after\nconst res = await fetch(`https://dev.to/api/articles/${id}`);\nif (!res.ok) { console.warn(`article ${id} unavailable (${res.status})`); return; }\nawait cli.devto.read({ id });","handlingStrategy":"try-catch","validationCode":"const res = await fetch(`https://dev.to/api/articles/${id}`);\nif (res.ok) { const a = await res.json(); if (a?.id) { /* safe to proceed */ } }","typeGuard":"function isArticle(a) { return !!a && typeof a === 'object' && typeof a.id === 'number'; }","tryCatchPattern":"try { await cli.devto.read({ id }); }\ncatch (e) { if (e.name === 'EmptyResultError') { console.warn(`article ${id} not found`); return null; } throw e; }","preventionTips":["Validate the id is numeric before calling (matches the CLI's own ArgumentError for non-numeric ids).","Probe dev.to/api/articles/<id> once and cache known-good ids.","Handle deleted/unpublished articles as a normal empty case, not a crash.","Watch for DEV.to rate limiting which can surface as empty responses."],"tags":["http","empty-result","devto","api"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}