{"record":{"id":"424af30458bf2f60","repo":"Hmbown/CodeWhale","slug":"thread-summary-returned-http-response-statuscode","errorCode":null,"errorMessage":"Thread summary returned HTTP ${response.statusCode}.","messagePattern":"Thread summary returned HTTP (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/vscode/src/runtime.ts","lineNumber":119,"sourceCode":"    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  }\n  if (response.statusCode !== 200) {\n    throw new Error(`Restore points returned HTTP ${response.statusCode}.`);\n  }","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/extensions/vscode/src/runtime.ts#L101-L137","documentation":"After the staged manifest validates, its [plugin].name is checked by validate_skill_name_segment because that name becomes the installation directory under the user plugins dir. The name is rejected when empty, whitespace-padded or containing any whitespace, equal to '.' or '..', containing '/' or '\\\\', or otherwise not a single normal path component. This is the staged-time twin of the plugin_target_path guard, failing before any copy happens.","triggerScenarios":"The staged bundle's plugin.json has a name like \"Data Sync\", \"tools/exporter\", \"..\", or an empty string; validate_staged extracts the name and the segment check fails.","commonSituations":"Authors putting display names into [plugin].name; copy-pasting a name with a trailing newline or space; third-party bundles authored against looser conventions; names containing Windows separators.","solutions":["Set [plugin].name to a single path-safe slug: no whitespace, no separators, not '.'/'..' (e.g. \"data-sync\").","Use a description/title field for the human-readable name and keep the name field machine-safe.","Lint manifests before publishing: reject names that trim unevenly or contain path characters."],"exampleFix":"// before (plugin.json)\n{ \"plugin\": { \"name\": \"Data Sync Plugin\" } }\n\n// after\n{ \"plugin\": { \"name\": \"data-sync\", \"description\": \"Data Sync Plugin\" } }","handlingStrategy":"validation","validationCode":"let name = validated.manifest.plugin.name.clone();\nif !is_safe_plugin_name(&name) {\n    anyhow::bail!(\"[plugin].name must be one path-safe segment, got '{name}'\");\n}","typeGuard":"fn is_safe_plugin_name(name: &str) -> bool {\n    !name.is_empty()\n        && name.trim() == name\n        && !name.chars().any(char::is_whitespace)\n        && !matches!(name, \".\" | \"..\")\n        && !name.contains('/') && !name.contains('\\\\')\n}","tryCatchPattern":"match validate_staged(&staged_path) {\n    Ok(v) => v,\n    Err(e) if e.to_string().contains(\"[plugin].name is not a safe directory name\") =>\n        return Err(e).context(\"rename the plugin in its manifest to a slug and reinstall\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Use slug-style names in [plugin].name; keep display titles in description.","Trim and inspect names for hidden whitespace when copying from documentation.","Lint third-party bundles with the segment validator before distributing them."],"tags":["rust","plugins","install","path-safety","validation"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}