vercel/ai · error · Error
Invalid AI SDK harness skills manifest: ${manifestPath}
Error message
Invalid AI SDK harness skills manifest: ${manifestPath} What it means
Thrown by readSkillsManifest in packages/harness/src/utils/write-skills.ts when the skills manifest file (.ai-sdk-harness-skills.json) exists in the sandbox but is not valid JSON or fails the SkillsManifest structure/type check (version, state, skills entries). The harness uses this manifest to track which skills it manages, so a corrupt manifest is treated as a hard failure rather than silently ignored.
Source
Thrown at packages/harness/src/utils/write-skills.ts:303
}
async function readSkillsManifest({
sandbox,
manifestPath,
abortSignal,
}: {
sandbox: Experimental_SandboxSession;
manifestPath: string;
abortSignal?: AbortSignal;
}): Promise<SkillsManifest | undefined> {
const content = await sandbox.readTextFile({
path: manifestPath,
abortSignal,
});
if (content == null) return undefined;
const parsed = await safeParseJSON({ text: content });
if (!parsed.success || !isSkillsManifest(parsed.value)) {
throw new Error(`Invalid AI SDK harness skills manifest: ${manifestPath}`);
}
return parsed.value;
}
function isSkillsManifest(value: unknown): value is SkillsManifest {
if (value == null || typeof value !== 'object' || Array.isArray(value)) {
return false;
}
const manifest = value as Record<string, unknown>;
if (
manifest.version !== SKILLS_MANIFEST_VERSION ||
(manifest.state !== 'complete' && manifest.state !== 'pending') ||
!Array.isArray(manifest.skills)
) {
return false;
}
const names = new Set<string>();
for (const entry of manifest.skills) {View on GitHub (pinned to 69428b1f8b)
Solutions
- Delete or restore the corrupt .ai-sdk-harness-skills.json in rootDir, then re-run writeSkills (directories not owned by the harness may need manual cleanup).
- Let the harness regenerate the manifest instead of editing it by hand.
- Verify the manifest matches { version: 1, state: 'complete'|'pending', skills: [{ name, hash }] }.
- Check for concurrent processes writing skills to the same rootDir simultaneously.
Example fix
// before (rootDir/.ai-sdk-harness-skills.json, hand-edited)
{ "version": 2, "skills": "all of them" }
// after — delete the corrupt manifest and re-run
await sandbox.run({ command: 'rm /workspace/.ai-sdk-harness-skills.json' });
await writeSkills({ sandbox, rootDir, skills }); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the manifest before the harness reads it
const raw = await sandbox.run({ command: 'cat ' + rootDir + '/.ai-sdk-harness-skills.json' });
if (raw.exitCode === 0) {
const ok = (() => { try { const m = JSON.parse(raw.stdout); return m.version === 1 && ['complete','pending'].includes(m.state) && Array.isArray(m.skills); } catch { return false; } })();
if (!ok) await sandbox.run({ command: 'rm ' + rootDir + '/.ai-sdk-harness-skills.json' });
} Type guard
function isSkillsManifest(v: unknown): v is { version: 1; state: 'complete'|'pending'; skills: { name: string; hash: string }[] } {
return typeof v === 'object' && v !== null && !Array.isArray(v) &&
(v as any).version === 1 &&
['complete','pending'].includes((v as any).state) &&
Array.isArray((v as any).skills);
} Try / catch
try {
await writeSkills({ sandbox, rootDir, skills });
} catch (error) {
if (/Invalid AI SDK harness skills manifest/.test((error as Error).message)) {
await sandbox.run({ command: `rm -f ${rootDir}/.ai-sdk-harness-skills.json` });
await writeSkills({ sandbox, rootDir, skills }); // regenerate
} else throw error;
} Prevention
- Never hand-edit .ai-sdk-harness-skills.json.
- Avoid concurrent writeSkills calls against the same rootDir.
- After upgrading the AI SDK, remove stale manifests generated by older versions.
- Keep manifest writes inside the harness so they stay atomic/consistent.
When it happens
Trigger: Calling writeSkills where rootDir contains a .ai-sdk-harness-skills.json that was hand-edited, truncated by a previous crash, written by an incompatible SDK version, or is valid JSON but missing required fields (version 1, state 'complete'|'pending', skills array of {name, hash}).
Common situations: Manual editing of the manifest file; interrupted writes from an older version; another tool overwriting the file; version mismatch after upgrading the AI SDK harness.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- 'HarnessAgent: `sandboxConfig.onBootstrap` and `sandboxConfi
- Failed to resolve sandbox default working directory: expecte
- Invalid host tool catalog.
- The Claude Code harness requires an explicit `portEndpoint`
- Harness 'claude-code' requires a JSON schema for structured
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/3226ed707e2a0d87.
Report an issue: GitHub.