{"record":{"id":"e82831a0482e5e10","repo":"jackwener/OpenCLI","slug":"packagist-package-returned-no-package-object-for","errorCode":null,"errorMessage":"packagist package returned no \"package\" object for ${full}.","messagePattern":"packagist package returned no \"package\" object for (.+?)\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/packagist/package.js","lineNumber":28,"sourceCode":"cli({\n    site: 'packagist',\n    name: 'package',\n    access: 'read',\n    description: 'Fetch a Packagist package\\'s metadata (version, downloads, license, repo, GitHub stars)',\n    domain: 'packagist.org',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [\n        { name: 'name', positional: true, required: true, help: 'Composer package \"<vendor>/<package>\" (e.g. \"symfony/console\", \"monolog/monolog\")' },\n    ],\n    columns: ['package', 'version', 'releasedAt', 'license', 'description', 'repository', 'githubStars', 'favers', 'downloads', 'monthlyDownloads', 'dailyDownloads', 'url'],\n    func: async (args) => {\n        const { full } = requirePackageName(args.name);\n        const url = `${PACKAGIST_BASE}/packages/${full}.json`;\n        const body = await packagistFetch(url, 'packagist package');\n        const pkg = body?.package;\n        if (!pkg || typeof pkg !== 'object') {\n            throw new CommandExecutionError(`packagist package returned no \"package\" object for ${full}.`);\n        }\n        const versionKey = pickStableVersion(pkg.versions);\n        const versionEntry = versionKey ? pkg.versions?.[versionKey] : null;\n        const license = Array.isArray(versionEntry?.license) ? versionEntry.license.filter(Boolean).join(', ') : '';\n        const downloads = pkg.downloads ?? {};\n        return [{\n            package: String(pkg.name ?? full).trim(),\n            version: versionKey ? String(versionKey) : '',\n            releasedAt: trimDate(versionEntry?.time),\n            license,\n            description: String(pkg.description ?? '').trim(),\n            repository: String(pkg.repository ?? '').trim(),\n            githubStars: pkg.github_stars != null ? Number(pkg.github_stars) : null,\n            favers: pkg.favers != null ? Number(pkg.favers) : null,\n            downloads: downloads.total != null ? Number(downloads.total) : null,\n            monthlyDownloads: downloads.monthly != null ? Number(downloads.monthly) : null,\n            dailyDownloads: downloads.daily != null ? Number(downloads.daily) : null,\n            url: `https://packagist.org/packages/${full}`,","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/packagist/package.js#L10-L46","documentation":"Packagist's /packages/<vendor>/<name>.json endpoint responded, but the JSON body had no usable `package` object (missing, null, or not an object). Thrown as a CommandExecutionError because it indicates the response shape differs from what the CLI expects.","triggerScenarios":"`packagist package` fetched `${PACKAGIST_BASE}/packages/${full}.json` after requirePackageName parsed the name; the response JSON parsed but `body.package` was absent or not an object — e.g. Packagist changed its schema or served an error page as JSON.","commonSituations":"Packagist API schema change; the fetch layer returning an error envelope (e.g. {status:'error'}) instead of package data; a cached/proxied response missing the package key; querying a package that exists in search but whose detail endpoint returns an empty document.","solutions":["Log the raw response body from `${PACKAGIST_BASE}/packages/${full}.json` to see what was actually returned","Verify the package exists: open the same URL or https://packagist.org/packages/<vendor>/<name> in a browser","Update the CLI — Packagist occasionally adjusts its JSON schema","Confirm packagistFetch isn't swallowing error statuses and returning a non-package body"],"exampleFix":"// before\nconst pkg = body?.package;\nif (!pkg) throw new Error('no package');\n// after\nconst pkg = body?.package ?? body?.['package'] ?? null;\nif (!pkg || typeof pkg !== 'object') {\n  console.error('Unexpected Packagist payload:', JSON.stringify(body).slice(0, 300));\n  throw new Error('no package object');\n}","handlingStrategy":"validation","validationCode":"const url = `https://repo.packagist.org/p2/${vendor}/${name}.json`;\nconst ok = await fetch(url).then(r => r.ok).catch(() => false);\nif (!ok) throw new Error(`Package ${vendor}/${name} not found on Packagist`);","typeGuard":"function isPackagistPackageBody(b) { return b != null && typeof b === 'object' && b.package != null && typeof b.package === 'object'; }","tryCatchPattern":"try {\n  const info = await packagistPackage('vendor/name');\n  return info;\n} catch (e) {\n  if (/no \"package\" object/.test(e.message)) {\n    console.error('Unexpected Packagist payload — check schema or package existence');\n    return null;\n  }\n  throw e;\n}","preventionTips":["Validate vendor/name format before calling (lowercase, one slash)","Check the package detail JSON in a browser when the CLI reports a shape error","Keep the CLI current; Packagist metadata endpoints (p2) evolve","Inspect the raw response body when the parsed shape is unexpected"],"tags":["api","schema","packagist"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}