{"record":{"id":"35f071b4b0735e2a","repo":"Hmbown/CodeWhale","slug":"thread-summaries-require-the-runtime-bearer-token","errorCode":null,"errorMessage":"Thread summaries require the runtime bearer token.","messagePattern":"Thread summaries require the runtime bearer token\\.","errorType":"exception","errorClass":"Error","httpStatus":401,"severity":"error","filePath":"extensions/vscode/src/runtime.ts","lineNumber":116,"sourceCode":"    kind: \"connected\",\n    baseUrl,\n    detail: version ? `Connected to CodeWhale ${version}.` : \"Connected to CodeWhale runtime.\",\n    version,\n  };\n}\n\nexport async function listThreadSummaries(\n  config: RuntimeConfig,\n  limit = 8,\n): Promise<ThreadSummary[]> {\n  const baseUrl = runtimeBaseUrl(config);\n  const response = await requestJson(\n    `${baseUrl}/v1/threads/summary?limit=${encodeURIComponent(String(limit))}`,\n    config.token,\n  );\n\n  if (response.statusCode === 401) {\n    throw new Error(\"Thread summaries require the runtime bearer token.\");\n  }\n  if (response.statusCode !== 200) {\n    throw new Error(`Thread summary returned HTTP ${response.statusCode}.`);\n  }\n\n  return readThreadSummaries(response.body);\n}\n\nexport async function listSnapshots(config: RuntimeConfig, limit = 8): Promise<SnapshotEntry[]> {\n  const baseUrl = runtimeBaseUrl(config);\n  const response = await requestJson(\n    `${baseUrl}/v1/snapshots?limit=${encodeURIComponent(String(limit))}`,\n    config.token,\n  );\n\n  if (response.statusCode === 401) {\n    throw new Error(\"Restore points require the runtime bearer token.\");\n  }","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/extensions/vscode/src/runtime.ts#L98-L134","documentation":"validate_staged found a manifest at the staged root, but PluginManifest::validate_from_path rejected its contents — a parse failure (malformed JSON/TOML) or a schema violation such as a missing/invalid [plugin] table or name. The staged copy is only accepted after the manifest validates and its content hash is computed, so this aborts the install before anything reaches the user plugins directory. The underlying validator error is chained into the message, so the full anyhow chain names the offending field.","triggerScenarios":"Installing a bundle whose plugin.json is syntactically broken, is missing the required plugin.name field, or carries a structure the current manifest schema rejects; e.g. a bundle authored for a different plugin spec version than the installer supports.","commonSituations":"Typos while hand-writing plugin.json (trailing commas, wrong table name in TOML); plugin specs from an incompatible client version; manifests generated by a script that emitted an error body; empty manifest file from a failed checkout or partial download.","solutions":["Read the chained {error} — it names the exact parse/validation failure; fix that field in the source manifest.","Open the staged manifest and validate it locally: it must parse and carry a valid [plugin] section with a name.","Compare against a known-good bundle's manifest shape — mismatched top-level structure is the usual cause after spec changes.","Re-download or rebuild the bundle if the manifest looks truncated or contains an error page."],"exampleFix":"# before: plugin.json fails validation\n{ \"plugin\": { \"nam\": \"demo\" } }\n\n# after\n{ \"plugin\": { \"name\": \"demo\", \"version\": \"0.1.0\" } }","handlingStrategy":"validation","validationCode":"let manifest_path = crate::plugins::agent_plugin::resolve_manifest_path(source)\n    .context(\"bundle has no root manifest\")?;\nPluginManifest::validate_from_path(&manifest_path)\n    .map_err(|e| anyhow::anyhow!(\"fix the manifest before staging: {e}\"))?;","typeGuard":"fn bundle_validatable(bundle: &Path) -> bool {\n    crate::plugins::agent_plugin::resolve_manifest_path(bundle)\n        .and_then(|m| std::fs::read_to_string(m).ok())\n        .map(|raw| serde_json::from_str::<serde_json::Value>(&raw).is_ok())\n        .unwrap_or(false)\n}","tryCatchPattern":"match validate_staged(&staged_path) {\n    Ok((name, hash)) => (name, hash),\n    Err(e) if e.to_string().contains(\"staged plugin manifest failed validation\") =>\n        return Err(e).context(\"repair the plugin.json/plugin.toml in the source bundle and reinstall\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Validate the manifest in the source repo before packaging, not after staging.","Run a JSON/TOML linter over plugin manifests in CI.","Keep bundles on the manifest schema version the installer supports; re-test after upgrading.","Treat unparseable manifests in downloads as corruption: re-fetch rather than patch."],"tags":["rust","plugins","install","manifest","validation"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}