{"record":{"id":"f606b4bc0601e840","repo":"Hmbown/CodeWhale","slug":"restore-points-returned-http-response-statuscode","errorCode":null,"errorMessage":"Restore points returned HTTP ${response.statusCode}.","messagePattern":"Restore points returned HTTP (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/vscode/src/runtime.ts","lineNumber":136,"sourceCode":"  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  }\n  if (response.statusCode !== 200) {\n    throw new Error(`Restore points returned HTTP ${response.statusCode}.`);\n  }\n\n  return readSnapshots(response.body);\n}\n\nexport function startRuntimeTerminal(config: RuntimeConfig): vscode.Terminal {\n  const terminal = vscode.window.createTerminal(\"CodeWhale Runtime\");\n  const args = [\n    \"serve\",\n    \"--http\",\n    \"--host\",\n    shellQuote(config.host),\n    \"--port\",\n    String(config.port),\n  ];\n  if (config.token) {\n    args.push(\"--auth-token\", shellQuote(config.token));\n  }","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/extensions/vscode/src/runtime.ts#L118-L154","documentation":"The source bundle of a local install has a manifest, but PluginManifest::validate_from_path rejected it (parse error or schema violation) before any bytes were copied to staging. Validating first means a bad manifest never reaches the user plugins directory, and the underlying {error} from the validator is chained so the specific field problem is visible in the full error chain.","triggerScenarios":"stage_local_copy on a directory whose plugin.json/plugin.toml is malformed (bad JSON/TOML syntax, missing [plugin].name, invalid structure) — validation runs immediately after the manifest is located, before canonicalize/copy.","commonSituations":"Hand-edited manifests with syntax errors; bundles authored for a different manifest schema version; manifests truncated by a partial download; TOML manifests using the wrong table name.","solutions":["Read the chained {error} — it names the exact parse/validation failure; fix that field in the source manifest.","Validate the manifest yourself first: parse plugin.json with a JSON linter or run PluginManifest::validate_from_path on it.","If the bundle came from a third party, check for an updated release compatible with the current manifest schema."],"exampleFix":"# before: plugin.json is invalid JSON (trailing comma)\n{ \"plugin\": { \"name\": \"demo\", } }\n\n# after\n{ \"plugin\": { \"name\": \"demo\" } }","handlingStrategy":"validation","validationCode":"let manifest = source.join(\"plugin.json\");\nlet raw = std::fs::read_to_string(&manifest)\n    .with_context(|| format!(\"read {}\", manifest.display()))?;\nserde_json::from_str::<serde_json::Value>(&raw)\n    .map_err(|e| anyhow::anyhow!(\"source manifest is not valid JSON: {e}\"))?;\nstage_local_copy(source, user_plugins_dir, max_size)?;","typeGuard":"fn manifest_parses(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            || raw.parse::<toml::Value>().is_ok())\n        .unwrap_or(false)\n}","tryCatchPattern":"match stage_local_copy(source, plugins_dir, max_size) {\n    Ok(staged) => staged,\n    Err(e) if e.to_string().contains(\"source is not a valid plugin bundle\") =>\n        return Err(e).context(format!(\"fix the manifest in {} first\", source.display()))),\n    Err(e) => return Err(e),\n}","preventionTips":["Validate the source manifest with PluginManifest::validate_from_path before calling install.","Diff the manifest against a known-good bundle after schema upgrades.","Reject partial downloads: re-fetch bundles whose manifest fails to parse."],"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"}