{"record":{"id":"3fc6f0978edca4ad","repo":"jackwener/OpenCLI","slug":"no-upwork-job-posting-found-for-id-id-may-be","errorCode":null,"errorMessage":"No Upwork job posting found for id \"${id}\" (may be closed, expired, or private)","messagePattern":"No Upwork job posting found for id \"(.+?)\" \\(may be closed, expired, or private\\)","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/upwork/detail.js","lineNumber":92,"sourceCode":"                    buyer: s.buyer ? JSON.parse(JSON.stringify(s.buyer)) : null,\n                };\n            })()`));\n        }\n        catch (e) {\n            throw new CommandExecutionError(`Failed to read Upwork job-detail store: ${e?.message ?? e}`, 'The Vuex store was not reachable; try again after opening Upwork in the connected browser.');\n        }\n\n        if (payload?.onLogin) {\n            throw new AuthRequiredError('upwork.com', 'Upwork redirected to login. Open https://www.upwork.com in the connected browser and sign in, then retry.');\n        }\n        if (payload?.challenge) {\n            throw new CommandExecutionError('Upwork served a Cloudflare challenge page', 'Open https://www.upwork.com in the connected browser and clear the challenge, then retry.');\n        }\n        if (!isPlainObject(payload)) {\n            throw new CommandExecutionError('Upwork detail returned an unexpected Browser Bridge payload shape');\n        }\n        if (!payload?.ready || !payload.job) {\n            throw new EmptyResultError('upwork detail', `No Upwork job posting found for id \"${id}\" (may be closed, expired, or private)`);\n        }\n        if (!isPlainObject(payload.job)) {\n            throw new CommandExecutionError('Upwork job-detail store had an unexpected job shape; expected an object.');\n        }\n\n        const job = payload.job;\n        const returnedCiphertext = String(job?.ciphertext ?? '').trim();\n        if (returnedCiphertext && returnedCiphertext !== id) {\n            throw new CommandExecutionError(`Upwork job-detail store returned ciphertext \"${returnedCiphertext}\" while reading \"${id}\".`);\n        }\n        const buyer = payload.buyer || {};\n        const stats = buyer?.stats || {};\n        const location = buyer?.location || {};\n        const category = job?.category?.name || '';\n        const skills = formatSkills(job);\n        const totalSpent = Number(stats?.totalCharges?.amount);\n        const totalHires = Number(stats?.totalJobsWithHires);\n        const score = Number(stats?.score);","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/upwork/detail.js#L74-L110","documentation":"When the payload is valid but payload.ready is false or payload.job is missing, the command concludes no job data exists for the given id and throws EmptyResultError naming the id and likely causes (closed, expired, or private posting). This distinguishes 'authentically no data' from auth/challenge/shape failures.","triggerScenarios":"Calling upwork detail with a job id whose posting is no longer visible: job closed or expired by the buyer, made private, deleted, wrong/typo'd id, or the SPA hasn't finished loading the job (ready:false) when the store was read.","commonSituations":"Scraping stale job ids from old search results; fetching a job that requires login to view while the payload skips it; querying too quickly after page load before the Vuex store populates; ids from a different Upwork locale/domain.","solutions":["Verify the job id is correct and open the job URL manually in the browser to confirm it's still public.","If the page is still loading, retry after it fully renders (ready can be false during hydration).","Log in to Upwork in the connected browser — private/login-required postings won't expose job data otherwise.","Accept closed/expired jobs as terminal: filter such ids out of your pipeline instead of retrying.","If the job is visible in the browser but the error persists, update the library — the ready/job extraction may be outdated."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!/^(~\\w+\\/)?[0-9a-f]{16,20}$/i.test(jobId) && !~jobId.indexOf('/')) {\n  console.warn('Job id looks malformed; verify the URL/id before fetching.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const detail = await fetchUpworkJobDetail(id);\n} catch (e) {\n  if (e instanceof EmptyResultError) {\n    console.warn(`Job ${id} unavailable (closed/expired/private) — skipping.`);\n    return null;\n  }\n  throw e;\n}","preventionTips":["Open the job URL manually to confirm it's still live before automation fetches.","Log in first — private or login-required postings surface as empty results.","Wait for full page load; reading the store too early yields ready:false.","Treat closed/expired ids as terminal and filter them from retry queues."],"tags":["upwork","empty-result","scraping","job-detail"],"backgroundTag":"empty-result-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}